ObjectContext.LoadProperty未加载相关实体

时间:2012-09-04 21:16:06

标签: entity-framework entity-framework-4

我遇到ObjectContext.LoadProperty(EF 4数据库优先)的困难(字符串和表达式重载对我来说都表现出相同的行为)。给出以下简单模式:

Product
--------------
ProductId (pk)
...

Order
--------------
OrderId (pk)
...

OrderItem
--------------
OrderId (pk, fk Order),
ItemNumber (pk),
ProductId (fk Product)
...

因为我发现它在我的特定场景中的性能优于Includes,所以我使用LoadProperty来填充相关实体。例如,

Order ord = context.Orders.Where(o => o.OrderId = 1).FirstOrDefault();

context.LoadProperty(ord, o => o.Items); // Items is the navigation property name for the
                                            OrderItem -> Order relationship

foreach(var i in ord.Items)
{
    context.LoadProperty(i, oi => oi.Product);
}

这已经存在了一段时间并且已经有效(正如您所期望的那样)就好了。但是,今天早上我们开始遇到一种情况,即使在调用LoadProperty之后,i.Product仍然为空。 i.ProductId有效,我甚至可以明确地加载产品:

var product = context.Products.Where(p => p.ProductId == i.ProductId).FirstOrDefault();

LoadProperty不会加载该对象。抛出没有异常,它只是不加载它。我也试过指定MergeOptions.OverwriteChanges(即使没有),结果可以预测相同。

什么可能导致ObjectContext.LoadProperty以这种方式无声地失败?

1 个答案:

答案 0 :(得分:0)

我发现这似乎是一个问题(如果不是一个彻头彻尾的错误)与EF的LoadProperty功能的工作方式。

OrderItemProduct表的ProductId值因大小写,尾随空格或两者而异。鉴于SQL Server的默认排序规则,这是合法的,并且保持了参照完整性。这就是为什么对产品的查询有效的原因,但似乎EF在某处内部进行了关键比较,并对这些值进行了更严格的判断。

如果您自己遇到此问题,可以在查询中使用T-SQL DATALENGTH函数检查尾随空格,并且可以使用不同的排序规则来比较大小写。

例如,您可以使用以下内容查看上述模型中的差异:

select
    *

from OrderItem oi

join Product p on p.ProductId = oi.ProductId -- default collation; case and 
                                             -- trailing spaces ignored

where DATALENGTH(oi.ProductId) <> DATALENGTH(p.Product) -- trailing spaces differ
   or oi.ProductId <> p.ProductId COLLATE SQL_Latin1_General_CP1_CS_AS -- case differs

请注意,可以仅使用排序规则来比较尾随空格和字符大小写;如果有人知道这样做的排序规则的名称,请随时编辑此答案或发表评论,我会更新。在那之前,这应该做必要的事情。