1

在我的代码实体框架中只加载一个导航属性

//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

作者 ID 7b1fc9c4-4930-45be-9196-44b3f49e6770

作者为NULL?错误的

纪念编号 a813a8f4-409b-4c97-8d2d-cb19aff267bb

纪念是NULL吗?真的 ???

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

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

附言

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

纪念是NULL吗?错误的 ???

4

1 回答 1

3

I assume that db.CurrentUser is a User entity. Apparently in your AddData method this entity is already loaded because you are using:

md.AuthorId = db.CurrentUser.Id;

(If not, you would get a NullReferenceException.)

When you set the AuthorId EF will set the Author navigation property as well when DetectChanges is called (happens inside of db.MemorialDatas.Add) because the Author (=db.CurrentUser) is in memory and probably attached to the context.

The Memorial entity is not loaded, you seem to have only the model.MemorialId available.

Your test to write and read the MemorialData happens in the same context and ...

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

...doesn't run a database query because you have added it to the context before, hence Find can return it from memory with md.Author being set.

md.Memorial is not set and when you access it EF won't run a lazy loading query because you didn't create a dynamic proxy but just a plain Entity with md = new MemorialData().

In order to fix the problem and to enable lazy loading so that md.Memorial can be loaded from the database you must create a dynamic proxy (instead of md = new MemorialData();):

md = db.MemorialDatas.Create();
于 2013-05-25T14:50:53.837 回答