外部ソースからデータを xml としてロードしています。データは逆シリアル化され、オブジェクトをループ処理してドメイン エンティティに注ぎ込みます。
データ間の関係を作成し、データベース呼び出しを削減するために、アイテムが見つからない場合は最初に DbSet.Local からアイテムを取得しようとする拡張メソッドを作成し、次に示すように DbSet.SingleOrDefault() を使用してデータベースをクエリします。 .
public static TEntity SingleOrDefaultLocalFirst<TEntity>(this IDbSet<TEntity> set,
Func<TEntity, bool> predicate) where TEntity : class
{
if (set == null)
throw new ArgumentNullException("set");
if (predicate == null)
throw new ArgumentNullException("predicate");
TEntity results = null;
try
{
results = set.Local.SingleOrDefault(predicate);
}
catch (Exception e)
{
Debug.WriteLine(e.Message, "Error");
}
if (results != null)
{
return results;
}
return set.SingleOrDefault(predicate);
}
try catch ブロックは、修正しようとしている問題を抑制するためにあります。
何らかの理由で、ローカル ストアをクエリするときのナビゲーション プロパティが設定されていません。したがって、次のようなものを使用すると
(x=>x.Participant.Event.ExternalId==newItem.Id)
私のラムダとして、参加者の nav プロパティは null です。
このコードで常に null 参照エラーが発生しないようにする方法が必要だと思います。
ループが使用を開始する前に、データベースから参加者とイベントのデータを明示的にロードしようとしました
context.Participant.Load()
しかし、これは違いはありません。
ナビゲーション プロパティが null である理由と、それらを最も効率的に設定する方法を誰か教えてもらえますか?
そして、なぜ私が Find() を使用しないのか不思議に思っている人がいれば、それは、外部データが多くのプロパティと、私のシステムの主キーではない外部 ID フィールドにキー付けされているためです。
アップデート:
実際のコードを含めるのに時間をかけるつもりはありません。使用可能な例に絞り込むには多すぎるため、Customer/Order/OrderItem の典型的な例を使用してみます。
本当の問題は、ネストされたエンティティがあり、次のようなものを使用して存在を確認しようとする場合です。
var orderLine = context.OrderLineItems.Local.SingleOrDefault(x=>x.Order.Number == 1234)
これを使用する前に、Orders と Customers がコンテキストに明示的に読み込まれている場合でも、Order の nullreference エラーがスローされます。
context.Orders.Load()
しかし、これを行うと:
var orderLine = context.OrderLineItems.SingleOrDefault(x=>x.Order.Number == 1234)
それが動作します。
Local を呼び出すときに機能しない理由を理解したい。関連する nav プロパティが既にコンテキストに読み込まれているのに、データベースにアクセスして関連するプロパティを取得する必要があるのはなぜですか? または私は何かを逃していますか?