C# - 实体框架代码优先,延迟加载不起作用
Posted
技术标签:
【中文标题】C# - 实体框架代码优先,延迟加载不起作用【英文标题】:C# - Entity Framework Code first, lazy loading not working 【发布时间】:2020-12-11 08:23:42 【问题描述】:我在使用 SQL Server 数据库的 Entity Framework 6 代码优先方面存在一些问题。 我有一个现有的数据库,我想将它们与实体框架一起使用。在 Visual Studio 2017 中,我添加了一个 ADO.NET 实体数据模型类型的新项目,以首次生成代码优先类。
一旦生成了类,我就开始使用对象与数据库进行交互。这里我有一些延迟加载的问题。一些导航属性为空。导航属性标有virtual
,延迟加载和ProxyCreationEnabled
为真。
这些屏幕截图说明了问题:
我可以分享 Visual Studio 生成的类:
public partial class ETRFContext : DbContext
static string conn = "My connection string";
public ETRFContext() : base(conn)
public virtual DbSet<Acessos> Acessos get; set;
public virtual DbSet<Caracteristicas> Caracteristicas get; set;
public virtual DbSet<CircuitoAprovacoes> CircuitoAprovacoes get; set;
public virtual DbSet<EstadosEstudo> EstadosEstudo get; set;
public virtual DbSet<Estudos> Estudos get; set;
public virtual DbSet<GruposAcesso> GruposAcesso get; set;
public virtual DbSet<HistoricoDetalhadoEstudo> HistoricoDetalhadoEstudo get; set;
public virtual DbSet<MembrosGruposAcesso> MembrosGruposAcesso get; set;
public virtual DbSet<Normas> Normas get; set;
public virtual DbSet<Paises> Paises get; set;
public virtual DbSet<PrecedenciasEstudos> PrecedenciasEstudos get; set;
public virtual DbSet<PrecedenciasProgramas> PrecedenciasProgramas get; set;
public virtual DbSet<Programas> Programas get; set;
public virtual DbSet<Projetos> Projetos get; set;
public virtual DbSet<RegistosCAD> RegistosCAD get; set;
public virtual DbSet<TiposEstadoEstudo> TiposEstadoEstudo get; set;
public virtual DbSet<TiposMensagem> TiposMensagem get; set;
public virtual DbSet<TiposProjeto> TiposProjeto get; set;
protected override void OnModelCreating(DbModelBuilder modelBuilder)
modelBuilder.Entity<Caracteristicas>()
.Property(e => e.Chave)
.IsFixedLength();
modelBuilder.Entity<Caracteristicas>()
.Property(e => e.Valor)
.IsFixedLength();
modelBuilder.Entity<Estudos>()
.HasMany(e => e.EstadosEstudo)
.WithRequired(e => e.Estudos)
.HasForeignKey(e => e.idEstudo);
modelBuilder.Entity<Estudos>()
.HasMany(e => e.HistoricoDetalhadoEstudo)
.WithRequired(e => e.Estudos)
.HasForeignKey(e => e.idEstudo);
modelBuilder.Entity<Estudos>()
.HasMany(e => e.PrecedenciasEstudos)
.WithRequired(e => e.Estudos)
.HasForeignKey(e => e.idEstudo);
modelBuilder.Entity<Estudos>()
.HasMany(e => e.PrecedenciasEstudos1)
.WithRequired(e => e.Estudos1)
.HasForeignKey(e => e.idEstudoPrecedencia)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Estudos>()
.HasMany(e => e.RegistosCAD)
.WithRequired(e => e.Estudos)
.HasForeignKey(e => e.idEstudo);
modelBuilder.Entity<GruposAcesso>()
.HasMany(e => e.Acessos)
.WithRequired(e => e.GruposAcesso)
.HasForeignKey(e => e.idGruposAcesso);
modelBuilder.Entity<GruposAcesso>()
.HasMany(e => e.MembrosGruposAcesso)
.WithRequired(e => e.GruposAcesso)
.HasForeignKey(e => e.idGrupoAcesso);
modelBuilder.Entity<Paises>()
.HasMany(e => e.Projetos)
.WithOptional(e => e.Paises)
.HasForeignKey(e => e.id_Pais);
modelBuilder.Entity<Programas>()
.HasMany(e => e.Acessos)
.WithRequired(e => e.Programas)
.HasForeignKey(e => e.idPrograma);
modelBuilder.Entity<Programas>()
.HasMany(e => e.CircuitoAprovacoes)
.WithRequired(e => e.Programas)
.HasForeignKey(e => e.idPrograma);
modelBuilder.Entity<Programas>()
.HasMany(e => e.Estudos)
.WithRequired(e => e.Programas)
.HasForeignKey(e => e.idProgramas);
modelBuilder.Entity<Programas>()
.HasMany(e => e.PrecedenciasProgramas)
.WithRequired(e => e.Programas)
.HasForeignKey(e => e.idProgramaPrecedencia);
modelBuilder.Entity<Programas>()
.HasMany(e => e.PrecedenciasProgramas1)
.WithRequired(e => e.Programas1)
.HasForeignKey(e => e.idPrograma)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Projetos>()
.HasMany(e => e.Caracteristicas)
.WithRequired(e => e.Projetos)
.HasForeignKey(e => e.id_projeto);
modelBuilder.Entity<Projetos>()
.HasMany(e => e.Estudos)
.WithRequired(e => e.Projetos)
.HasForeignKey(e => e.idProjetos);
modelBuilder.Entity<TiposEstadoEstudo>()
.HasMany(e => e.EstadosEstudo)
.WithRequired(e => e.TiposEstadoEstudo)
.HasForeignKey(e => e.idEstado);
modelBuilder.Entity<TiposMensagem>()
.HasMany(e => e.HistoricoDetalhadoEstudo)
.WithRequired(e => e.TiposMensagem)
.HasForeignKey(e => e.idTipoMensagem);
modelBuilder.Entity<TiposProjeto>()
.HasMany(e => e.Programas)
.WithRequired(e => e.TiposProjeto)
.HasForeignKey(e => e.idTiposProjeto);
modelBuilder.Entity<TiposProjeto>()
.HasMany(e => e.Projetos)
.WithRequired(e => e.TiposProjeto)
.HasForeignKey(e => e.id_Tipo)
.WillCascadeOnDelete(false);
现在这是Estudos
类:
public partial class Estudos
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Estudos()
EstadosEstudo = new HashSet<EstadosEstudo>();
HistoricoDetalhadoEstudo = new HashSet<HistoricoDetalhadoEstudo>();
PrecedenciasEstudos = new HashSet<PrecedenciasEstudos>();
PrecedenciasEstudos1 = new HashSet<PrecedenciasEstudos>();
RegistosCAD = new HashSet<RegistosCAD>();
public int id get; set;
public int idProjetos get; set;
public int idProgramas get; set;
[Required]
[StringLength(25)]
public string NomeEstudo get; set;
[Required]
[StringLength(5)]
public string Utilizador get; set;
public DateTime DataInicial get; set;
public DateTime? DataFinal get; set;
public bool Producao get; set;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<EstadosEstudo> EstadosEstudo get; set;
public virtual Programas Programas get; set;
public virtual Projetos Projetos get; set;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<HistoricoDetalhadoEstudo> HistoricoDetalhadoEstudo get; set;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<PrecedenciasEstudos> PrecedenciasEstudos get; set;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<PrecedenciasEstudos> PrecedenciasEstudos1 get; set;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<RegistosCAD> RegistosCAD get; set;
还有班级Projetos
:
public partial class Projetos
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Projetos()
Caracteristicas = new HashSet<Caracteristicas>();
Estudos = new HashSet<Estudos>();
public int id get; set;
[Required]
[StringLength(15)]
public string projeto get; set;
public int id_Tipo get; set;
[StringLength(50)]
public string Cliente get; set;
[StringLength(50)]
public string Designacao get; set;
public int? id_Pais get; set;
public int? CalculoEletrico get; set;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Caracteristicas> Caracteristicas get; set;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Estudos> Estudos get; set;
public virtual Paises Paises get; set;
public virtual TiposProjeto TiposProjeto get; set;
我注意到的一件事是,当我在数据库中查询“Estudo”时,我没有得到导航属性“Projetos”,但是当我向数据库询问“Projetos”时,我得到了导航属性“Estudos” ”。
另一件事是,当我在数据库中查询“Estudo”时,我没有获得导航属性“Projetos”,但如果我在数据库中查询 id = Estudo.idProjetos 的“Projetos”,则导航“Estudos”中的“Projetos”属性之前为空,自动填充关联“Projeto”的值。
那么,有人有解决这个问题的技巧吗?
感谢您的帮助。
【问题讨论】:
在查询中使用Include
告诉它您要填充哪些导航属性。
这不是一个最小的例子......
@juharr,是的,这解决了我的问题,非常感谢。但是你可以解释一下为什么在这种情况下我需要把 Include 填满导航属性?
@MarcoTeixeira 基本上 EF 不会填充导航属性,除非您告诉它以避免可能更复杂和昂贵的查询。如果我想要的只是一个表中的数据,让它从与它有关系的表中提取所有数据,而这些表与之有关系的表等等可能会使查询花费更长的时间并返回比需要的更多的数据。
【参考方案1】:
在您的Estudos
实体中,您能否将ForeignKey
属性添加到Programas
和Projetos
属性。
[ForeignKey("idProgramas")]
public virtual Programas Programas get; set;
[ForeignKey("idProjetos")]
public virtual Projetos Projetos get; set;
并且在查询Estudos
时包括Programas
和Projetos
。
db.Estudos
.Include(x => x.Programas)
.Include(x => x.Projetos)
.ToList();
【讨论】:
以上是关于C# - 实体框架代码优先,延迟加载不起作用的主要内容,如果未能解决你的问题,请参考以下文章