2011-02-07 10 views
2

私は、次のスキーマがあります。SQLクエリにLinq to SQLクエリ内の計算カラムを参照できますか?

product 
- productID (PK) 
- name 
- units 

purchase 
- purchaseID (PF) 
- productID (FK) 
- soldUnits 
- woUnits 

boxContents 
- boxID (PK) 
- puchaseID (FK) 
- count 

と、次のLINQを:

var qStockLevel = from pr in db.products 
    select new 
    { 
     pr.productID, 
     pr.name, 
     totalUnits = (from pu in db.purchases 
         where pu.productID == pr.productID 
         select pu).Count() * pr.units, 

    sold = (from pr2 in db.products 
      join pu in db.purchases on pr.productID equals pu.productID into pp 
      where pr2.productID == pr.productID 
      from pu2 in pp.DefaultIfEmpty() 
      select (int?) pu2.soldUnits ?? 0).Sum(), 

    writtenOff = (from pr2 in db.products 
       join pu in db.purchases on pr.productID equals pu.productID into pp 
       where pr2.productID == pr.productID 
       from pu in pp.DefaultIfEmpty() 
       select (int?)pu.woUnits ?? 0).Sum(), 

    onDisplay = (from pr2 in db.products 
       join bc in db.boxContents on pr.productID equals bc.purchase.productID into bp 
       where pr2.productID == pr.productID 
       from bc in bp.DefaultIfEmpty() 
       select (int?)bc.count ?? 0).Sum(), 

    available = (totalUnits - sold - writtenOff - onDisplay), 
}; 

末尾に「利用可能」の欄には動作しませんが、私はそれを含めました私が達成しようとしているもの、つまり既に生成された列から計算された列を示します。これは可能ですか?私はプレゼンテーション層でそれを行うことができましたが、これが最初に機能するかどうかを確認したかったのです。

また、私の(Linq初心者の)目には、writtenOffを生成して列を売っているため、クエリが非効率的に見えます。集約関数が関わっているときに、これを達成するためのよりよい方法がありますか?

ありがとうございました。

EDIT

もう一つ - 私は「利用可能」とは(あなたがする必要があります最後から二番目の行のために{} [新規]を選択します> 0

答えて

0

である行を返したいですもう一度必要なすべてのフィールドをコピーしてください)。その後、where句を追加します。

EDIT:実際には関係ありませんが、使用可能な値を保持している新しい列が得られるようですINotityPropertyChanging、それは実装が非常に簡単です)

2

ここでは、必要な操作を行うためのクエリを紹介します。

var query = from product in context.Products 
      where 
      (
       product.Purchases.Count() * product.units - 
       product.Purchases.Sum(purchase => purchase.soldUnits ?? 0) - 
       product.Purchases.Sum(purchase => purchase.woUnits ?? 0) - 
       product.Purchases.SelectMany(purchase => purchase.BoxContents).Sum(bc => bc.count ?? 0) 
      ) > 0 
      select product; 

そして、FYI、ここにあなたがあなたを設定することができ一つの方法です:

は(あなたのDBMLデザイナーに>BoxContents - - >PurchasesこれはあなたがProductとの関連付けを設定したことを想定しています。注意してください) Productクラス。

(あなたは熱心な負荷Productさんの子どもたちにDataLoadOptions.LoadWith()を使用する場合があります。)

public partial class Product 
{ 
    public int TotalUnits 
    { 
     get { return this.Purchases.Count * this.units ?? 0; } 
    } 

    public int Sold 
    { 
     get { return this.Purchases.Sum(p => p.soldUnits ?? 0); } 
    } 

    public int WrittenOff 
    { 
     get { return this.Purchases.Sum(p => p.woUnits ?? 0); } 
    } 

    public int OnDisplay 
    { 
     get { return this.Purchases.SelectMany(p => p.BoxContents).Sum(b => b.count ?? 0); } 
    } 

    public int Available 
    { 
     get { return TotalUnits - Sold - WrittenOff - OnDisplay; } 
    } 
}