C# “LINQ到SQL”;聚合;财产
假设我有一个C# “LINQ到SQL”;聚合;财产,c#,.net,linq,linq-to-sql,C#,.net,Linq,Linq 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 {
订单表
和一个付款表
每次付款都与给定的订单相关: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()
};
LINQtoSQL正好生成我想要的SQL查询
我的问题是,我正在向现有应用程序添加支付支持。因此,为了尽量减少代码影响,我希望totalPaid
成为我的Order
类的一个属性
我想添加一个“manual”属性,并尝试在查询时填充它。
但是,编写select子句是我遇到的难题:
var query = from o in db.Orders
where o.blah = blah
select "o with o.totalPaid = (from p in db.Payments <snip>).Sum()"
var query=从o开始,以db.Orders为单位
其中o.blah=blah
选择“o,o.TotalPayment=(从db.Payments.Sum()中的p开始)”
我该怎么做?通常,您的
订单
类将有一个名为付款
的导航属性。利用此功能,您的TotalPaid
属性将如下所示:
public double TotalPaid
{
get { return Payments.Sum(x => x.Amount); }
}
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
这解决了另一个问题:此属性始终是最新的。一旦订单中添加了新的付款,您的方法就会过时
如果保持最新并不重要,但可以减少往返数据库的次数,则可以使用以下代码:
private double? _totalPaid;
public double TotalPaid
{
get
{
if(!_totalPaid.HasValue)
_totalPaid = Payments.Sum(x => x.Amount);
return _totalPaid.Value;
}
}
您可以在Orders类中添加指向payments类的PaymentySet,还可以按照Daniel Hilgarth的建议声明TotalPaymed属性 但是,当您查询数据库中的订单时,LinqToSql将对每个订单进行1次查询,以获得付款总额。解决方法是使用DataContext.LoadWith()方法,如下所示:
public double TotalPaid
{
get { return Payments.Sum(x => x.Amount); }
}
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
DataContext db=newdatacontext(connStr);
DataLoadOptions dlo=新的DataLoadOptions();
dlo.LoadWith(o=>o.Payments);
db.LoadOptions=dlo;
var query=以db.Orders为单位从o开始
其中o.blah=blah
//这将在单个查询中加载带有订单的付款
可能使用聚合
方法,而不是求和
方法?请注意,select“some string”
是什么……leppie,这不是字符串,这是我想要实现的,但找不到如何编码;-)我猜您缺少使用System.Linq的丹尼尔,很有趣。问题是,计算每个订单的TotalPaid需要一个往返过程:-(您可以通过缓存该值来优化它,但这样就不能保证它是最新的。