Я создаю приложение NET Core MVC, которое использует существующую базу данных MS SQL. Первичные ключи и внешние ключи уже установлены и работают правильно на уровне базы данных.
Я последовал примеру этой статьи и использовал консоль диспетчера пакетов для обратного инжиниринга моделей и контекста базы данных из базы данных. Это, казалось, работало хорошо. В результате все модели были добавлены в папку Models моего приложения, включая надежный класс контекста базы данных. У меня проблема в том, что реляционная информация об этих объектах не заполняется во время выполнения. Я получаю значения NULL для связанных объектов, для которых внешние ключи установлены как в базе данных, так и в свободном API-коде, созданном процессом скаффолдинга.
У меня есть две таблицы, Mode и Submode, связанные через внешний ключ.
Леса сгенерировали эти два класса для двух вышеупомянутых таблиц:
public partial class Submode
{
public Submode()
{
Contact = new HashSet<Contact>();
}
public int Id { get; set; }
public int ModeId { get; set; }
public string Code { get; set; }
public bool Visible { get; set; }
public bool IsDefault { get; set; }
public Mode Mode { get; set; }
public ICollection<Contact> Contact { get; set; }
}
public partial class Mode
{
public Mode()
{
Contact = new HashSet<Contact>();
Submode = new HashSet<Submode>();
}
public int Id { get; set; }
public string Code { get; set; }
public bool Visible { get; set; }
public bool IsDefault { get; set; }
public ICollection<Contact> Contact { get; set; }
public ICollection<Submode> Submode { get; set; }
}
Scaffolding также сгенерировал этот свободный фрагмент API в контексте базы данных:
modelBuilder.Entity<Submode>(entity =>
{
entity.HasIndex(e => e.Code)
.HasName("UQ__Submode__A25C5AA75D2A9AE7")
.IsUnique();
entity.Property(e => e.Code)
.IsRequired()
.HasMaxLength(100)
.IsUnicode(false);
entity.HasOne(d => d.Mode)
.WithMany(p => p.Submode)
.HasForeignKey(d => d.ModeId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_Submode_ModeId");
});
Каждый пример, который я читал о настройке внешних ключей с помощью свободного API, показывает шаблон, подобный приведенным выше фрагментам. Но для Submode Mode возвращается к нулю.
Ноль во время выполнения
И я получаю исключение нулевой ссылки в возвращенном представлении, потому что я пытаюсь отобразить свойства связанного объекта Mode. Я пропустил какую-то конфигурацию или есть проблема со скаффолдинговым кодом?
UDPATE - по запросу, вот реализация, которая извлекает данные из контекста базы данных.
public class SQLSubModeData : ISubModeData
{
private w4lkrContext _context;
public SQLSubModeData(w4lkrContext context)
{
_context = context;
}
public IQueryable<Submode> Get()
{
return _context.Submode.OrderBy(p => p.Id);
}
public Submode Get(int id)
{
return _context.Submode.FirstOrDefault(p => p.Id == id);
}
}
ОБНОВЛЕНИЕ (решено) - Включение отложенной загрузки решило проблему. Три шага привели меня туда:
Установленные Microsoft.EntityFrameworkCore.Proxies (2.1.2) через NuGet
Обновлен метод Startup.cs -> AddDbContext (), как показано ниже:
services.AddDbContext (options => options.UseLazyLoadingProxies (). UseSqlServer (_configuration.GetConnectionString ("W4LKR")));
Сделаны все свойства навигации виртуальными. Это должно было быть сделано для каждой модели в приложении, а не только для той, которая вызывается в моем примере выше. Ошибки выдаются, если хотя бы один из них пропущен.