2011-05-31 101 views
4

假設我有一個表Orders和一個表PaymentsLINQ to SQL「聚合」屬性

每次付款涉及給定的順序:Payment.orderId

我想查詢我的訂單:

var query = from o in db.Orders where o.blah = blah select o; 

但我還需要支付每個訂單總:

var query = from o in db.Orders 
      where o.blah = blah 
      select new 
      { 
       Order = o, 
       totalPaid = (from p in db.Payments 
           where p.orderId == o.id 
           select p.Amount).Sum() 
      }; 

LINQ to SQL生成我想要的SQL查詢。

我的問題是我將付款支持添加到現有的應用程序。因此,爲了儘量減少代碼的影響,我想totalPaid是我的Order類的財產。

我想添加一個「手動」屬性,並試圖在查詢時填充它。 可是我在寫SELECT子句就是我堅持:

var query = from o in db.Orders 
      where o.blah = blah 
      select "o with o.totalPaid = (from p in db.Payments <snip>).Sum()" 

我怎麼能這樣做?

+0

也許使用'Aggregate'方法而不是'Sum'一個?注意確定'選擇'一些字符串''雖然... – leppie 2011-05-31 15:04:39

+0

跛腳,這不是一個字符串,這是我想要實現,但無法找到如何編碼;-) – 2011-05-31 15:15:59

回答

7

通常,您的Order類將具有一個名爲Payments的導航屬性。利用這一點,你TotalPaid屬性應該是這樣的:

public double TotalPaid 
{ 
    get { return Payments.Sum(x => x.Amount); } 
} 

這解決了另一個問題:該屬性始終是最新的。只要將新付款添加到訂單中,您的方法就會過時。

如果是跟上時代的不那麼重要,但減少往返次數到數據庫中,你可以使用此代碼:

private double? _totalPaid; 

public double TotalPaid 
{ 
    get 
    { 
     if(!_totalPaid.HasValue) 
      _totalPaid = Payments.Sum(x => x.Amount); 
     return _totalPaid.Value; 
    } 
} 
+0

+1:但可能'付款。 Sum(x => x.Amount)':) – leppie 2011-05-31 15:06:48

+0

@leppie:對,你是。 – 2011-05-31 15:07:29

+0

我想你錯過了'使用System.Linq;'。 – 2011-05-31 15:32:53

2

您可以添加一個支付EntitySet的詮釋訂單類指向Payments類,並根據Daniel Hilgarth的建議聲明TotalPaid屬性。

但是,當您爲訂單查詢數據庫時,LinqToSql將爲每個訂單進行1次查詢,以獲得付款總額。解決方法是使用像這樣的DataContext.LoadWith()方法:

DataContext db = new Datacontext(connStr); 
DataLoadOptions dlo = new DataLoadOptions(); 
dlo.LoadWith<Orders>(o=>o.Payments); 
db.LoadOptions = dlo; 
var query = from o in db.Orders 
      where o.blah = blah 
//this will load the payments with the orders in a single query