简体   繁体   English

实体框架 - Include()加载所有chidren属性,甚至是虚拟属性

[英]Entity framework - Include() loads all chidren properties even virtual ones

I am trying to build a model with Entity Framework - Code First in which I use a "Exam" class and a "Subject" class that have a many-to-many relationship. 我正在尝试使用Entity Framework构建一个模型 - Code First,其中我使用了一个“Exam”类和一个具有多对多关系的“Subject”类。
A "Exam" contains a list of "Subject" (Subjects). “考试”包含“主题”(主题)列表。
A "Subject" contains a list of "Exam" (Exams). “主题”包含“考试”(考试)列表。

Both "Exams" and "Subjects" are virtual properties. “考试”和“科目”都是虚拟属性。

When I use context.Exams.Include("Subjects").ToList(); 当我使用context.Exams.Include("Subjects").ToList(); , I get all the exams and all the subjects related to each exam, which is OK. ,我得到所有考试和所有与每个考试相关的科目,这是可以的。 The problem is I also get all the exams related to the subjects. 问题是我也得到了与科目相关的所有考试。

Result : 结果:

  1. Exam 1 考试1
    • Subject 1 主题1
      • Exam 3 考试3
      • Exam 4 考试4
    • Subject 2 主题2
      • Exam 3 考试3
  2. Exam 2 ... 考试2 ...


In this particular case, I don't need the exams related to the subjects. 在这种特殊情况下,我不需要与科目相关的考试。 I just need the following data : 我只需要以下数据:

  1. Exam 1 考试1
    • Subject 1 主题1
    • Subject 2 主题2
  2. Exam 2 ... 考试2 ...


Is there a way to include "Subjects" but without the "Exams" property ? 有没有办法包括“主题”但没有“考试”属性?


Thank you. 谢谢。

Function 功能

public List<Exam> GetAllExams()
    {
        using (var context = new PedagogieContext())
        {
            return context.Exams.Include("Subjects").ToList();
        }
    }

Classes

public class Exam
{
    public int Id { get; set; }
    public string ExamLabel { get; set; }
    public virtual List<Subject> Subjects { get; set; }
}

public class Subject
{
    public int Id { get; set; }
    public string SubjectLabel { get; set; }
    public virtual List<Exam> Exams { get; set; }
}

Mappings 映射

class SubjectMap : EntityTypeConfiguration<Subject>
{
    public SubjectMap()
    {
        this.HasKey(e => e.Id);
        this.Property(e => e.Id).HasColumnName("KeyDiscipline");
        this.Property(e => e.SubjectLabel).HasColumnName("DisciplineLib");
        this.ToTable("vpDisciplines");
    }
}

class ExamMap : EntityTypeConfiguration<Exam>
{
    public ExamMap()
    {
        this.HasKey(e => e.Id);
        this.Property(e => e.Id).HasColumnName("KeyExamen");
        this.Property(e => e.ExamenLabel).HasColumnName("ExamenLib");
        this.ToTable("vExamens");

        this.HasMany(e => e.Subjects)
            .WithMany(d => d.Exams)
            .Map(m =>
            {
                m.ToTable("vrExamensDisciplines");
                m.MapLeftKey("KeyExamen");
                m.MapRightKey("KeyDiscipline");
            });

    }
}

Context 上下文

public class PedagogieContext : DbContext
{
    public PedagogieContext()
        : base(ConnectionStringManager.GetConnectionString())
    {
        this.Configuration.LazyLoadingEnabled = false;
    }

    public DbSet<Exam> Exams { get; set; }
    public DbSet<Subject> Subjects { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new ExamMap());
        modelBuilder.Configurations.Add(new SubjectMap());
    }
}

The "problem" is that Entity Framework executes relationship fixup whenever you get data from the database (and on many more occasions). “问题”是,无论何时从数据库获取数据(以及更多场合),实体框架都会执行关系修正 This is the process where EF automatically populates navigation properties (like Subject.Exams ) of entities in its cache. 这是EF自动填充其缓存中实体的导航属性(如Subject.Exams )的过程。

You are fetching exams and subjects and EF kindly populates their Subjects and Exams , respectively. 您正在参加考试和科目,EF分别填写他们的Subjects Exams There is no way to stop EF from doing this (some may think that setting Configuration.AutoDetectChangesEnabled = false will do that, but no). 没有办法阻止EF这样做(有些人可能认为设置Configuration.AutoDetectChangesEnabled = false会这样做,但没有)。

Note that you don't get more exams from the database than you get from the query, if that's what you're worried about. 请注意,如果您担心这一点,那么您从数据库中获得的考试数量不会超过您从查询中获得的考试数。 It's just that EF also creates the associations. 只是EF也创造了联想。 In a debug view you could expand the collections endlessly without ever hitting the database. 在调试视图中,您可以无限地扩展集合,而无需访问数据库。

The solution is not to display Subject.Exams . 解决方案不是显示Subject.Exams If this is for serialization, you have to block circular references. 如果这是用于序列化,则必须阻止循环引用。 Some serializers (like Json.Net) have settings to do that. 一些序列化程序(如Json.Net)有设置来做到这一点。

Thank you all for your answers. 谢谢大家的答案。
Indeed, entity framework doesn't load more exams than expected. 实际上,实体框架不会加载比预期更多的考试。 It just populates the sub-exams with the exams already loaded. 它只是填充了已经加载的考试的子考试。
My problem was actually a circular reference serializer issue. 我的问题实际上是一个循环引用序列化器问题。 I chose to use DTO (with automapper) to specify exactly the data I need in my view. 我选择使用DTO(使用automapper)在我的视图中准确指定我需要的数据。

http://cpratt.co/using-automapper-getting-started/ http://cpratt.co/using-automapper-getting-started/

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

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