2011-01-26 2 views
1

は、次のLINQクエリ考えてみましょう:どのようにオブジェクトをLinqの変数と他のいくつかのフィールドを選択するには?

from r in result 
join oUS in onOrderUS on r.ItemGUID equals oUS.ItemGUID into jOnOrderUS 
from oUS in jOnOrderUS.DefaultIfEmpty() 
let OnOrderUS = oUS != null ? oUS.UnitQty : 0 
select (new Func<ItemMinMaxView>(() => 
{ 
    r.OnOrderUS = OnOrderUS; 

    return r; 
})).Invoke() 

を私は結果からRを選択したいのですが、組織単位(OU)からのデータでフィールドを埋めます。これを行うより良い方法はありますか?

答えて

1

をやりたいだろう。しかし、私はReactive Extensions (Rx)を利用して、あなたが望む副作用(すなわち、値の割り当て)を引き起こすでしょう。

まず、アンソニーのようにクエリを作成しますが、クエリが正しいことを確認したいと思います。

複数のonOrderUSレコードが返された場合は、最後に検出されたレコードのみをItemMinMaxViewレコードに割り当てます。

レコードがゼロまたは1つしかない場合は、クエリは正常ですが、単純になる可能性があります。

いずれにせよ、代わりにこのクエリを試してみてください。

var output = query 
    .Do(x => x.Result.OnOrderUS = x.OnOrderUS) 
    .Select(x => x.Result) 
    .ToArray(); 

.Do(...)方法はの一部です:

var query = 
    from r in result 
    join oUS in onOrderUS on r.ItemGUID equals oUS.ItemGUID into goUSs 
    let OnOrderUS = goUSs.Sum(x => x.UnitQty) 
    select new 
    { 
     Result = r, 
     OnOrderUS 
    }; 

は、その後、私は(割り当ての副作用で)最終結果このように取得したいですこれらの種類の副作用については明示的に存在しています。

RxにIEnumerable<T>の良い拡張メソッドの負荷がかかりますので、チェックアウトしていないといいでしょう。最近ではsupported Microsoft developer toolに昇格しました。

2

あなたの機能が構成要素に分割されているとは思いますが最初のクエリ(結合、投影など)、突然変異、そして必要な特定の結果を返します。例えば、

var query = from r in result 
      join oUS in onOrderUS on r.ItemGUID equals oUS.ItemGUID into jOnOrderUS 
      from oUS in jOnOrderUS.DefaultIfEmpty() 
      let OnOrderUS = oUS != null ? oUS.UnitQty : 0 
      select new { r, OnOrderUS }; 

foreach (var item in query) 
{ 
    item.r.OnOrderUS = item.OnOrderUS; 
} 

return query.Select(item => item.r); 
// assumes this is in a method returning IEnumerable<R> 

foreachをコードしたくない場合は、次のように書くことができます。私は、クエリからの変異を好きではないが、これは私があまりにも読みやすさを支援するために、より論理的な部分に、クエリの分割を見たい

Func<R, int, R> mutateR = (r, onOrderUS) => { r.OnOrderUS = onOrderUS; return r; }; 

var query = from r in result 
      join oUS in onOrderUS on r.ItemGUID equals oUS.ItemGUID into jOnOrderUS 
      from oUS in jOnOrderUS.DefaultIfEmpty() 
      let OnOrderUS = oUS != null ? oUS.UnitQty : 0 
      select mutateR(r, OnOrderUS); 
+0

これは少し効果が少ないですか? foreachはデータを完全にループします。選択内のFuncは、データが選択されたときにこれを実行します。 – EtienneT

+0

@EtienneT、私はちょうど突然変異を見るのが好きではない。しかし、私はあなたがforeachなしで望むことをする編集を提供しました。 –

+0

これはFuncを宣言してクエリをインライン化して呼び出すのとほぼ同じことです。ご回答有難うございます! – EtienneT

関連する問題