重新加载实体和所有导航属性关联 - DbSet实体框架

Sam*_*Sam 30 c# ado.net entity-framework entity-framework-4.1

我有实体关联刷新的问题.当我得到一个像这样的实体:

MyContext context = new MyContext();

Person myPerson = context.PersonSet.FirstOrDefault();
String myPersonName = myPerson.Name;
Address myPersonAddress = myPerson.Address;
Run Code Online (Sandbox Code Playgroud)

我找到了一个名为Address的关联和名为Name的属性的人.如果我手动修改数据库中的数据,例如属性Name,我必须使用以下代码重新加载我的实体:

context.Entry(myPerson).Reload();
Run Code Online (Sandbox Code Playgroud)

我有Name的新值.但如果我为地址做同样的事情它也行不通.我认为这是因为地址是一个协会财产.我需要刷新它.

如何强制重新加载Address关联(以及Person类中的所有其他关联)?

编辑:

在同一个案例中,一个人可以拥有多个地址.

MyContext context = new MyContext();

Person myPerson = context.PersonSet.FirstOrDefault();
String myPersonName = myPerson.Name;
List<Address> myPersonAddresses = myPerson.Addresses;
Run Code Online (Sandbox Code Playgroud)

在这种情况下,它不是参考:

context.Entry(myPerson).Reference(p => p.Address).Load();
// Address will be populated with only the new address
// this isn't required because I use lazy loading
Run Code Online (Sandbox Code Playgroud)

但收藏品:

context.Entry(myPerson).Collection(p => p.Addresses).Load();
// Address will be populated with old value and new value
Run Code Online (Sandbox Code Playgroud)

我需要用它来工作:

context.Entry(myPerson).Collection(p => p.Addresses).CurrentValue.Clear();
context.Entry(myPerson).Collection(p => p.Addresses).Load();
Run Code Online (Sandbox Code Playgroud)

但对于我的所有导航属性来说,这似乎不是一个好的解决方案!

Sla*_*uma 29

如果你不使用延迟加载,你可以Address显式加载新的(因为你必须明确地加载它(Include例如),当你Person最初加载时):

context.Entry(myPerson).Reload();
// If the person refers to another Address in the DB
// myPerson.Address will be null now

if (myPerson.Address == null)
    context.Entry(myPerson).Reference(p => p.Address).Load();
    // myPerson.Address will be populated with the new Address now
Run Code Online (Sandbox Code Playgroud)

如果使用延迟加载,则不需要第二个代码块.尽管如此,只要您访问新属性myPerson.Address(例如上面第二个代码块中有新查询),就会获得对数据库的新查询,因为第一行会将导航属性标记为未加载(如果此人引用)数据库中的新地址.

此行为不取决于您是否在模型类中公开了外键.

似乎没有办法调用一个单一的魔术Reload方法,它可以在一次调用中重新加载和更新整个对象图(类似于没有单个Include来急切加载完整的对象图).

  • @Sam:我明白了.但我认为集合的逻辑是相同的(用`Collection`代替`Reference`).不幸的是,您必须为每个导航属性单独执行此操作(就像您必须为每个导航属性使用"Include"进行预先加载). (3认同)

Sat*_*ria 8

谢谢 !

context.Entry(myPerson).Collection(p => p.Addresses).Load();
Run Code Online (Sandbox Code Playgroud)

为我做了它的工作.

如果p.Addresses丢失了一个条目,则可以刷新

((IObjectContextAdapter)CurrentContext(context)).ObjectContext.Refresh(RefreshMode.StoreWins, p.Addresses);
Run Code Online (Sandbox Code Playgroud)

但如果它获得了一个条目,只有你的.Load()方法有帮助.再次感谢!