我想知道是否有可能连接添加到DbContext的新创建的(poco)实体(这样子对象就可以在导航中延迟加载)
var user = new User();
user.LocationID = 3;
dbContext.Users.Add(user);
var locationName = user.Location.Name;
(注意:我知道我可以获得Location对象并直接分配它,上面的例子只是为了解决这个问题)
(注意II:我可以创建一个代理对象,然后复制值,这样的对象会被连接(并进行延迟加载),但任何复杂的子对象(其他pocos)都不会包括在复制中)
有没有办法连接(或加载)添加的poco?
简单的答案是,当使用外键和POCO时,您可以在设置FK后显式延迟加载引用属性,如下所示:
context.Entry(e).Reference(propName).Load();
如果您需要经常遍历对象图,那么值得考虑的是,在概念级别而不是使用外键属性工作是否更容易。
当上下文跟踪导航属性表示的实体时,可以在DetectChanges()上同步FK和nav属性。文档表明,只有当对象具有永久密钥时,才会发生这种情况。
如果引用处于添加状态(在本例中,课程对象),则不会同步引用导航属性使用新对象的键值,直到调用SaveChanges为止。由于对象上下文没有包含已添加对象的永久关键帧,直到保存为止。
然而,文档似乎是不正确或误导性的,当使用处于Added
状态且没有永久密钥的新添加实体的属性时,导航属性和外键的同步仍然会发生。
下面是我自己的数据模型上的一些测试代码,我用来研究这个问题。这是将EF5与.Net 4一起使用,据我所知,实际上是EF4.3。
using (MyContext context = new MyContext())
{
/*
* Uncomment these lines to test assigning FK Id when entity is being tracked
*/
Customer cust1 = context.Customers.OrderBy(x => x.Id).First();
Customer cust2 = context.Customers.OrderBy(x => x.Id).Skip(1).First();
/*
* Uncomment these lines to test assigning FK Id
* without having entity loaded in ObjectStateManager
*/
//Customer cust1 = context.Customers.AsNoTracking().OrderBy(x => x.Id).First();
//Customer cust2 = context.Customers.AsNoTracking()
// .OrderBy(x => x.Id).Skip(1).First();
//new entities
Quote proxyQ = context.Quotes.Create();
Quote pocoQ = new Quote();
/*
* if adding the new entities to context before setting FK properties
* DetectChanges must be called later to attempt sync with nav props
*/
context.Quotes.Add(proxyQ);
context.Quotes.Add(pocoQ);
//set FK Customer ids
proxyQ.CustomerId = cust1.Id;
pocoQ.CustomerId = cust2.Id;
/*
* FK / nav prop sync happens on DetectChanges() if the Customer
* entity is being tracked
* it must be explicitly called if it has not been called using
* one of the AutoDetectChanges functions in order to sync
*/
context.ChangeTracker.DetectChanges();
/*
* Alternatively, if the new entities are added to context after setting FK props
* and AutoDetectChanges is enabled then DetectChanges is called implicitly and
* FK / nav prop sync will happen here if the matching Customer entity is
* being tracked by the context.
*/
//context.Quotes.Add(proxyQ);
//context.Quotes.Add(pocoQ);
/*
* If assigning FK Id and the entity the id represents is not tracked then
* proxy will lazy load Customer here.
*/
Console.WriteLine("Proxy quote with key {0} linked to customer with name {1}",
proxyQ.Id.ToString(), proxyQ.Customer != null ? proxyQ.Customer.Name : "null");
/*
* Obviously no lazy loading of Customer can occur here for a POCO
*/
Console.WriteLine("POCO quote with key {0} linked to customer with name {1}",
pocoQ.Id.ToString(), pocoQ.Customer != null ? pocoQ.Customer.Name : "null");
/*
* But we can explicit lazy load when using POCO if we have assigned
* an FK Customer Id to a POCO quote and the Customer entity is not
* being tracked by context
*/
//context.Entry(pocoQ).Reference("Customer").Load();
//Console.WriteLine("POCO quote with key {0} linked to customer with name {1}",
// pocoQ.Id.ToString(), pocoQ.Customer != null ? pocoQ.Customer.Name : "null");