如何解决LINQ to SQL的“聚合”属性
| 假设我有一个表Orders
和一个表Payments
。
每个付款都与给定的订单相关: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
类的一个属性。
我想到添加一个“ 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()\"
我怎样才能做到这一点?
解决方法
通常,您的
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;
}
}
, 您可以在Orders类中添加一个Payments EntitySet并指向Orders类,也可以根据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
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。