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

これはしばらく前から導入されており、(ご想像のとおり) うまく機能しています。しかし、今朝、 を呼び出した後でもLoadProperty,i.Productがまだ null であるというシナリオに遭遇し始めました。i.ProductId有効であり、次のように製品を明示的にロードすることもできます:

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

しかしLoadProperty、オブジェクトをロードしません。例外はスローされず、単にロードされません。私も指定しようとしましたがMergeOptions.OverwriteChanges(何もありませんが)、結果は予想通り同じでした.

ObjectContext.LoadPropertyこのようにサイレントに失敗する原因は何ですか?

4

1 に答える 1

0

これは、(完全なバグではないにしても) EF のLoadProperty機能の動作に問題があるように見えることがわかりました。

OrderItemおよびProductテーブルにはProductId、大文字と小文字、末尾のスペース、またはその両方が異なるの値がありました。SQL Server の既定の照合順序を考えると、これは正当であり、参照整合性が維持されていました。これが製品のクエリが機能した理由ですが、EF は内部のどこかでキーの比較を行っており、これらの値についてより厳密になっているようです。

この問題が発生した場合DATALENGTHは、クエリで T-SQL 関数を使用して末尾のスペースを確認し、別の照合順序を使用して大文字と小文字を比較できます。

たとえば、これを使用して上記のモデルの不一致を確認できます。

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 に答える