【问题标题】:Entity Framwork 5: Why is my entity's collection property empty?实体框架 5:为什么我的实体的集合属性为空?
【发布时间】:2012-12-07 00:44:47
【问题描述】:

我目前正在通过 Code First 方法学习实体框架 (EF)。我想在一个新创建的数据库(即由 EF 创建)上建模 Professors 和 Classes 之间的简单一对多关系。

在我的模型中,Professor 具有 Classes 的集合。 Class 总是有一个 Professor 与之关联(即相应的属性永远不会为空)。我可以创建和存储Class 和关联的Professor,但是当我访问从数据库中检索到的ProfessorClasses 属性时,它是空的。但是,可以从 Class 导航到其 Professor

考虑以下模型:

class Class
{
    public int Id { get; set; }
    public string Title { get; set; }
    public virtual Professor Professor { get; set; }
}

class Professor
{
    public int Id { get; set; }
    public string Name { get; set; }
    private ICollection<Class> classes = null;

    public virtual ICollection<Class> Classes
    {
        get { return classes ?? (classes = new HashSet<Class>()); }
        set { classes = value; }
    }
}

class ClassManager : DbContext
{
    public DbSet<Professor> Professors { get; set; }
    public DbSet<Class> Classes { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Class>().HasRequired(c => c.Professor);
    }
}

在我的主要方法中,我像这样创建和访问我的数据:

    using (ClassManager db = new ClassManager())
    {
        Professor p = new Professor() { Name = "McTest" };
        Class c = new Class() { Title = "Testing Tests", Professor = p };

        p.Classes.Add(c);

        db.Professors.Add(p);
        db.Classes.Add(c);

        Console.WriteLine(db.SaveChanges() + " change(s) saved.");
    }

    using (ClassManager db = new ClassManager())
    {
        foreach (Professor p in db.Professors)
            Console.WriteLine("Prof. " + p.Name + " gives " + p.Classes.Count 
                + " classes.");

        foreach (Class c in db.Classes)
            Console.WriteLine(c.Title + " (Prof. " + c.Professor.Name + ")");
    }

输出是:

3 change(s) saved.
Prof. McTest gives 0 classes.
Testing Tests (Prof. McTest)

生成的数据库架构是:

table Classes
    column Id (PK, int, not null)
    column Title (nvchar(max), null)
    column Professor_Id (FK, int, not null)
table Professors
    column Id (PK, int, not null)
    column Name (nvchar(max), null)

如您所见,Classes 集合属性不会出现在架构中的任何位置。这是故意的吗?

有人可以对此有所了解吗?我发现的所有示例都不会详细介绍集合属性。

【问题讨论】:

    标签: c# entity-framework entity-framework-5


    【解决方案1】:

    好的,经过数小时的搜索,我找到了解决方案。在查询数据库时,似乎必须明确指示 EF 加载实体的集合属性:

    foreach (Professor p in db.Professors.Include("Classes"))
        Console.WriteLine("Prof. " + p.Name + " gives " + p.Classes.Count
            + " classes.");
    

    Include 方法可以做到这一点。

    【讨论】:

    • 我可能在几年前就已经为你投票了,但最近又遇到了这个问题,你在这里的问答是我找到有效答案的第一个地方。 (我在 MSDN 中也发现了这个问题,但与最近的 MSDN 一样,并不是以某种形式让我得到一个明显有用的语法。)有时我无法相信 MS SQL 框架设计有多么奇怪。我也不敢相信这个问题只有 +1 票而且不容易找到。谢谢!
    【解决方案2】:

    我的主代码中两个分开的 using 语句是有意的。如果我将它们合并在一起,Classes 属性突然不为空,但我不明白为什么。

    如果 2 合并为 1,那么您“查询”存储在内存中的本地实体,而不是数据库。

    在您的第一个上下文中,您不需要将 professorclass 添加到上下文中。只需添加教授,class 也会被保存。

    检查数据库架构并确保实体正确映射到数据库。

    最后,将Professor 类更改为

    class Professor
    {
        public Professor()
        {
             Classes = new List<Class>();
        }
    
        public int Id { get; set; }
        public string Name { get; set; }
        public virtual ICollection<Class> Classes {get; set;}
    }
    

    我怀疑延迟加载被 is null 逻辑所取代以返回散列集。

    【讨论】:

    • 我应用了您建议的更改,但结果是一样的。我还用数据库模式的描述更新了我的问题。如果您发现任何异常情况,请查看。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-29
    • 1970-01-01
    • 2012-04-22
    • 2014-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多