我有一些看起来像这样的代码:
var query = from row in context.Orders.Include("Customer")
where row.Id = 5
select row;
var result = query.FirstOrDefault();
if(result == null)
{
result = new Order {CustomerId=5,...}
context.Orders.Add(result);
context.SaveChanges();
// at this point result.Customer is null
// and is not lazy-loaded by EF on access
}
return result;
正如您在上面的代码中看到的那样,如果插入发生,则结果的Customer属性不包括在内,稍后在我的代码中给我一个错误。
如何在插入result.Customer
时确保从数据库加载result
?我可以不手动选择吗?
答案 0 :(得分:3)
如果不选择它,EF就无法激活客户对象。你在这里只是一个Id。 Something 需要转到数据库并找到Id#5的客户对象。
EF不能在此处延迟加载,因为您的result
实际上是POCO Order
,而不是知道如何延迟加载的EF生成的代理。
最简单的方法可能是查询客户并按ID设置关系,而不是(或同样)设置ID: -
if(result == null)
{
result = new Order
{
Customer = context.Customers.Single(x => x.Id == 5);
...
};
context.Orders.Add(result);
context.SaveChanges();
}
或者,您可以使用context.Orders.Create()
,这样您就可以首先使用EF代理: -
if(result == null)
{
var result = context.Orders.Create();
result.CustomerId = 5;
...
}
请注意,根据您域中预期的行为,将查询和命令混合起来往往不是一个好主意。您可能想要围绕CQRS进行一些阅读 - 例如http://cqrs.nu/
创建订单是一项非常重要的操作。将它楔入一个查询,查找尚不存在的订单可能会回来并在将来咬你。