在我的代码中,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);
纪念馆是否为空?假???
答案 0 :(得分:3)
我认为db.CurrentUser
是User
实体。显然,在您的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();