-1

我在使用ObjectContext.LoadProperty(EF 4 Database First)时遇到了困难(字符串和表达式重载对我来说都表现出相同的行为)。给定以下简单模式:

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);
}

这已经存在了一段时间并且运行良好(如您所料)。然而,今天早上我们开始遇到一个场景,即使在调用之后LoadPropertyi.Product仍然为空。i.ProductId是有效的,我什至可以像这样明确加载产品:

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

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

什么可能导致ObjectContext.LoadProperty以这种方式静默失败?

4

1 回答 1

0

我发现这似乎是 EFLoadProperty功能工作方式的一个问题(如果不是彻底的错误)。

OrderItem和表的ProductProductId因大小写、尾随空格或两者而异。给定 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

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

于 2012-09-04T22:08:04.433 回答