C# 重新加载一个实体和所有导航属性关联- DbSet 实体框架
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9081244/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reload an entity and all Navigation Property Association- DbSet Entity Framework
提问by Sam
I have a problem with entity association refresh. When I get an entity with like this:
我有实体关联刷新的问题。当我得到这样的实体时:
MyContext context = new MyContext();
Person myPerson = context.PersonSet.FirstOrDefault();
String myPersonName = myPerson.Name;
Address myPersonAddress = myPerson.Address;
I got an a person with an association named Address and a property named Name. If I modify manually the datas in database for example the property Name, I have to use the following code to reload my entity:
我有一个人有一个名为 Address 的关联和一个名为 Name 的属性。如果我手动修改数据库中的数据,例如属性名称,我必须使用以下代码重新加载我的实体:
context.Entry(myPerson).Reload();
and I have the new value for Name. But If I do the same for Address it doesn't work. I think it is because Address is an association property. I need to refresh it.
我有名称的新值。但是如果我对 Address 做同样的事情,它就行不通了。我认为这是因为 Address 是一个关联属性。我需要刷新它。
How Can I do to force the reload of Address association (and all other association in Person class) ?
如何强制重新加载地址关联(以及 Person 类中的所有其他关联)?
EDIT:
编辑:
In the same case, a person can have more than one address.
在同一情况下,一个人可以有多个地址。
MyContext context = new MyContext();
Person myPerson = context.PersonSet.FirstOrDefault();
String myPersonName = myPerson.Name;
List<Address> myPersonAddresses = myPerson.Addresses;
In this case, it is not a Reference:
在这种情况下,它不是参考:
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
but a Collection:
但是一个集合:
context.Entry(myPerson).Collection(p => p.Addresses).Load();
// Address will be populated with old value and new value
I need to use this to work:
我需要使用它来工作:
context.Entry(myPerson).Collection(p => p.Addresses).CurrentValue.Clear();
context.Entry(myPerson).Collection(p => p.Addresses).Load();
But it doesn't seem to be a good solution to do this for all my navigation properties!
但是对于我的所有导航属性执行此操作似乎不是一个好的解决方案!
回答by Slauma
If you don't use lazy loading, you have the load the new Addressexplicitly (as you had to load it explicitly (with Include, for example), when you loaded the Personinitially):
如果您不使用延迟加载,则可以Address显式加载 new (因为您必须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
If you use lazy loading, you don't need the second code block. Nonetheless, you get a new query to the database as soon as you access properties of the new myPerson.Address(like you have a new query in the second code block above) because the first line will mark the navigation property as not loaded if the person refers to a new address in the DB.
如果使用延迟加载,则不需要第二个代码块。尽管如此,只要您访问新的属性myPerson.Address(就像您在上面的第二个代码块中有一个新的查询),您就会立即获得对数据库的新查询,因为如果此人引用,第一行会将导航属性标记为未加载数据库中的新地址。
This behaviour doesn't depend on whether you have exposed the foreign key in the model class or not.
此行为不取决于您是否已在模型类中公开外键。
There doesn't seem to be a way to call some single magic Reloadmethod which would reload and update the whole object graph in one call (similar like there is no single Includeto eager load a complete object graph).
似乎没有一种方法可以调用某个单一的魔术Reload方法,该方法会在一次调用中重新加载和更新整个对象图(类似于没有单一Include的急切加载完整的对象图)。
回答by Aleksey Timkov
You need to use Query()extension to modify your LINQ expression. Here it is an example on basis of my personcal code. In this code I reload Addresses collection with related AddressType navigation property for myPerson object and place the result into SomeList:
您需要使用Query()扩展来修改您的 LINQ 表达式。这是基于我的个人代码的示例。在此代码中,我使用 myPerson 对象的相关 AddressType 导航属性重新加载 Addresses 集合,并将结果放入 SomeList:
_DbContext.Entry<Person>(myPerson)
.Collection(i => i.Adresses) // navigation property for Person
.Query()
.Include("AddressType") // navigation property for Address
.OrderBy(i => i.Name)
.ThenBy(i => i.AddressType.AddressTypeName) // just an example
.Select(i => new someClass
{
SoomeField1 = i.SomeField1,
...
})
.ToList()
.ForEach(i => SomeList.Add(i)); // SomeList is a List<T>
回答by specialist
I've solved this problem with using Detach before reading object from dbContext. This method allowed me to refresh all navigation properties of the object. I've described my scenario and details of solution here Entity Framework: Reload newly created object / Reload navigation properties
我在从 dbContext 读取对象之前使用 Detach 解决了这个问题。这个方法允许我刷新对象的所有导航属性。我已经在实体框架中描述了我的场景和解决方案的详细信息 :重新加载新创建的对象/重新加载导航属性
回答by Satria
Thank you !
谢谢 !
context.Entry(myPerson).Collection(p => p.Addresses).Load();
did its job for me.
为我做了它的工作。
If p.Addresses lost one entry, it can be refreshed by
如果 p.Addresses 丢失了一个条目,可以通过
((IObjectContextAdapter)CurrentContext(context)).ObjectContext.Refresh(RefreshMode.StoreWins, p.Addresses);
but if it gained one entry, only your .Load() method helped. Thanks again!
但如果它获得了一个条目,只有您的 .Load() 方法有帮助。再次感谢!

