0

これを処理する最善の方法を決定するのに苦労しています... Entity Framework (および L2S) では、LINQ クエリは IQueryable を返します。DAL/BLL が IQueryable、IEnumerable、または IList を返すかどうかについて、さまざまな意見を読みました。IList を使用すると仮定すると、クエリはすぐに実行され、その制御は次のレイヤーに渡されません。これにより、単体テストなどが容易になります。より高いレベルでクエリを絞り込むことはできなくなりますが、クエリを絞り込んで IList を返すことができる別のメソッドを作成することはできます。そして、さらに多くの長所/短所があります。ここまでは順調ですね。

今度は Entity Framework と遅延読み込みです。.NET 4/VS 2010 でプロキシを使用して POCO オブジェクトを使用しています。プレゼンテーション レイヤーでは次のことを行います。

foreach (Order order in bll.GetOrders())
{
  foreach (OrderLine orderLine in order.OrderLines)
  {
    // Do something
  }
}

この場合、GetOrders() は IList を返すため、PL に戻る直前に実行されます。しかし、次の foreach では、すべての OrderLine を取得するときに複数の SQL クエリを実行する遅延読み込みがあります。したがって、基本的に、PL は間違ったレイヤーで「オンデマンド」で SQL クエリを実行しています。

これを回避する賢明な方法はありますか?遅延読み込みをオフにすることはできますが、EF1 にはないと誰もが不平を言っているこの「機能」があることに何の意味があるのでしょうか。そして、多くのシナリオで非常に役立つことは認めます。したがって、いくつかのオプションがあります。

  1. どういうわけか、エンティティ内のすべての関連付けを削除し、それらを返すメソッドを追加します。これは、既定の EF の動作/コード生成に反し、一部の複合 (複数エンティティ) LINQ クエリの実行が難しくなります。一歩後退したようです。私は反対票を投じます。
  2. とにかく遅延読み込みがあり、単体テストが困難な場合は、最後まで行って IQueryable を返します。レイヤーをさらに細かく制御できます。IQueryable は L2S、L2E、または独自の IQueryable の完全な実装に結びついているため、これはまだ良い選択肢ではないと思います。遅延読み込みは「オンデマンド」でクエリを実行する場合がありますが、特定のインターフェイスに縛られることはありません。私は反対票を投じます。
  3. 遅延読み込みをオフにします。関連付けを手動で処理する必要があります。これは、熱心な読み込みの .Include() である可能性があります。いくつかの特定のケースでは、私は賛成票を投じます。
  4. IList と遅延読み込みを維持します。多くの場合、私は賛成票を投じますが、それは他の人たちとのトラブルのためだけです。

他のオプションや提案はありますか? 本当に納得できる選択肢が見つかりません。

4

1 に答える 1

0

メソッドに何らかのロード戦略を受け入れるようにすることができます。

Func<ObjectSet<Order>, ObjectQuery<Order>> loadSpan = 
orders=> orders.Include("OrderLines");

foreach (Order order in bll.GetOrders(loadSpan)) 
{ 
  foreach (OrderLine orderLine in order.OrderLines) 
  { 
    // Do something 
  } 
}

GetOrders メソッド内で、次のようなことを行います。

public IList<Oorder> GetOrders(
                     Func<ObjectSet<Order>, ObjectQuery<Order>> loadSpan)
{ 
    var ordersWithSpan = loadSpan(context.OrderSet);
    var orders = from order in ordersWithSpan
                 where ...your normal filters etc

    return orders.ToList();
}

これにより、ユースケースごとに負荷グラフ全体を指定できます。もちろん、これらの戦略をいくつかのラッパー クラスでラップすることもできるので、次のように記述します。

//wrapped in a static class "OrderLoadSpans"
foreach (Order order in bll.GetOrders(OrderLoadSpans.WithOrderLines))

HTH

于 2010-05-08T17:05:20.757 に答える