简体   繁体   English

C# - 实体框架代码优先,延迟加载不起作用

[英]C# - Entity Framework Code first, lazy loading not working

I have some issues with Entity Framework 6 code-first with a SQL Server database.我在使用 SQL 服务器数据库的 Entity Framework 6 代码优先方面遇到了一些问题。 I have an existing database, and I want to use them with Entity Framework.我有一个现有的数据库,我想将它们与 Entity Framework 一起使用。 With Visual Studio 2017, I add a new item of type ADO.NET Entity Data Model to generate the code-first classes for the first time.使用 Visual Studio 2017,我添加了一个类型为 ADO.NET 实体数据 Model 的新项目,以首次生成代码优先类。

Once the classes are generated, I start to use the objects to interact with the database.一旦生成了类,我就开始使用对象与数据库进行交互。 Here I have some issues with lazy loading.这里我有一些延迟加载的问题。 Some navigation properties are null. The navigation properties are marked with virtual and lazy loading and ProxyCreationEnabled are true.一些导航属性是null。导航属性标记为virtual和lazy loading并且ProxyCreationEnabled为true。

These screenshots illustrate the problem:这些屏幕截图说明了问题:

导航属性为空。

记录在数据库中

表之间的关系

I can share the classes generated by Visual Studio:我可以共享 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);
    }
}

Now this is the class Estudos :现在这是 class 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; }
}

And the class Projetos :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; }
}

One thing that I noticed, is when I query the Database for a "Estudo" I don't get the navigation property "Projetos", but when I ask the database for a "Projeto" I get the navigation property "Estudos".我注意到的一件事是,当我在数据库中查询“Estudos”时,我没有获得导航属性“Projetos”,但是当我向数据库查询“Projeto”时,我得到了导航属性“Estudos”。

Another thing is that when I query the database for a "Estudo" I don't get the navigation property "Projetos", but if then I query the database for a "Projeto" where id = Estudo.idProjetos, the navigation property "Projetos" in "Estudos" that was null before, automatically fills up with the value of associated "Projeto".另一件事是,当我在数据库中查询“Estudo”时,我没有获得导航属性“Projetos”,但是如果我在数据库中查询“Projeto”,其中 id = Estudo.idProjetos,导航属性“Projetos” " 在之前为 null 的 "Estudos" 中,自动填充关联 "Projeto" 的值。

So, anyone have some tips to solve this issue?那么,有人有解决这个问题的一些技巧吗?

Appreciate your help.感谢你的帮助。

In your Estudos entity, can you add ForeignKey attribute to Programas and Projetos properties.在您的Estudos实体中,您能否将ForeignKey属性添加到ProgramasProjetos属性。

[ForeignKey("idProgramas")]
public virtual Programas Programas { get; set; }

[ForeignKey("idProjetos")]
public virtual Projetos Projetos { get; set; }

And when querying Estudos include Programas and Projetos .在查询Estudos时,包括ProgramasProjetos

db.Estudos
  .Include(x => x.Programas)
  .Include(x => x.Projetos)
  .ToList();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM