#c# #.net #sql-server #entity-framework #entity-framework-core
Вопрос:
Я пытаюсь создать первые схемы кода с 2 сущностями:
- запрос
- сертификат
запрос может иметь (необязательно) сертификат, но у сертификата всегда есть запрос (ноль или один к одному)
Я определил сущность следующим образом :
public class Request
{
public virtual Certificate Certificate { get; set; }
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public long RequestID { get; set; }
public string fieldA { get; set; }
}
public class Certificate
{
public virtual Request Request { get; set; }
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public long RequestID { get; set; }
public string fieldB { get; set; }
}
И взаимосвязь четко определена в построителе моделей :
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Request>().ToTable("Requests");
modelBuilder.Entity<Certificate>().ToTable("Certificates");
modelBuilder.Entity<Request>()
.HasOne<Certificate>(item => item.Certificate)
.WithOne(item => item.Request)
.HasForeignKey<Certificate>(item => item.RequestID);
}
Модель построена правильно, и я могу сохранять сущности, но когда я запрашиваю запрос, у которого есть сертификат, свойство навигации остается нулевым :
Request req = await db.Requests.FirstOrDefaultAsync(item => item.RequestID == 1);
// req.Certificate is null
Что я упускаю ?
Использование EntityFrameworkCore V5.0.6 и .net 5
Комментарии:
Ответ №1:
Вам необходимо вручную включить свойства навигации. Попробуй
Request req = await db.Requests.Include(r => r.Certificate).SingleOrDefaultAsync(item => item.RequestID == 1);
Также вы можете избавиться от виртуального, если не хотите включить ужасную ленивую загрузку (по умолчанию отключена).
Комментарии:
1. Если прокси-серверы LazyLoad не включены, вам может потребоваться удалить
virtual
ключевое слово, иначе ядро EF будет загружено и даже.Include
не будет загружать связанную сущность. (На основе других сообщений о странностях /w.Include()
«не работает» в ядре EF.) Лично я использую LazyLoad как безотказный, но настоятельно рекомендую ознакомиться с проекцией (Select
/ProjectTo
), чтобы создавать более эффективные запросы, не сталкиваясь с проблемами ленивой/нетерпеливой загрузки.2. В конце концов я выяснил, где в EF6 ленивая загрузка была включена по умолчанию, здесь вы должны включить ее (с
optionsBuilder.UseLazyLoadingProxies()
) и добавитьMicrosoft.EntityFrameworkCore.Proxies
пакет3. ДА. Но не делай этого.
Ответ №2:
В EF core автоматические прокси-серверы (отложенная загрузка) по умолчанию отключены.
Чтобы включить их, установите пакет Microsoft.EntityFrameworkCore.Прокси
install-package Microsoft.EntityFrameworkCore.Proxies
и включите их в конструкторе опций
optionsBuilder.UseLazyLoadingProxies();