实体框架并非所有属性都加载

时间:2013-05-25 12:12:46

标签: c# entity-framework

在我的代码中,Entity Framework只加载一个导航属性

//Model
public class MemorialData
{
    public MemorialData()
    {
        Id = Guid.NewGuid();
    }

    [Key]
    public Guid Id { get; set; }

    public virtual Memorial Memorial { get; set; }
    public Guid MemorialId { get; set; }

    public virtual UserData Author { get; set; }
    public Guid AuthorId { get; set; }

    public string Data { get; set; }
}

public ActionResult AddData(MemorialData model)
{
    MemorialData md = db.MemorialDatas.Find(model.Id);
    if (md == null)
    {
        System.Diagnostics.Debug.WriteLine("md == null Creating");
        md = new MemorialData();
        md.MemorialId = model.MemorialId;
        //md.Memorial = db.Memorials.Find(model.MemorialId);
        md.Data = model.Data;
        md.AuthorId = db.CurrentUser.Id;
        db.MemorialDatas.Add(md);
    }
    else
    {
        md.Data = model.Data;
    }
    System.Diagnostics.Debug.WriteLine("Saving " + md.Id);
    db.SaveChanges();

    System.Diagnostics.Debug.WriteLine("Load " + md.Id);
    md = db.MemorialDatas.Find(md.Id);
    System.Diagnostics.Debug.WriteLine("AuthorId " + md.AuthorId);
    System.Diagnostics.Debug.WriteLine("Author is NULL? " + (md.Author == null));
    System.Diagnostics.Debug.WriteLine("MemorialId " + md.MemorialId);
    System.Diagnostics.Debug.WriteLine("Memorial is NULL? " + (md.Memorial == null));
}

调试输出

md == null创建

保存1b21f49f-749d-4cd3-8c3f-1f128ce67f6f

加载1b21f49f-749d-4cd3-8c3f-1f128ce67f6f

AuthorId 7b1fc9c4-4930-45be-9196-44b3f49e6770

作者是NULL?假

MemorialId a813a8f4-409b-4c97-8d2d-cb19aff267bb

纪念馆是否为空?真的???

为什么纪念馆为空但作者不为空?

在哪里可以找到错误原因?

P.S。

如果取消注释//md.Memorial = db.Memorials.Find(model.MemorialId);

纪念馆是否为空?假???

1 个答案:

答案 0 :(得分:3)

我认为db.CurrentUserUser实体。显然,在您的AddData方法中,此实体已经加载,因为您正在使用:

md.AuthorId = db.CurrentUser.Id;

(如果没有,你会得到NullReferenceException。)

当您设置AuthorId时,EF会在调用Author时调整DetectChanges导航属性(发生在db.MemorialDatas.Add内),因为Author (= db.CurrentUser)在内存中,可能附加到上下文中。

未加载Memorial实体,您似乎只有model.MemorialId可用。

您编写和阅读MemorialData的测试发生在相同的上下文中......

md = db.MemorialDatas.Find(md.Id);

...不会运行数据库查询,因为您之前已将其添加到上下文中,因此Find可以从设置了md.Author的内存中返回它。

md.Memorial未设置,当您访问它时,EF将不会运行延迟加载查询,因为您没有创建动态代理,只是创建了md = new MemorialData()的普通实体。

为了解决问题并启用延迟加载以便可以从数据库加载md.Memorial,您必须创建动态代理(而不是md = new MemorialData();):

md = db.MemorialDatas.Create();