我有一个特定的计算字段,我经常想要在Linq查询的“选择”字段中返回,例如今年的客户订单总数以及客户的其他人口统计信息。
public class Customer {
public decimal TotalPurchasesThisYear(MyDataContext db) {
return db.Orders.Where(o => o.CustomerID == ID)
.Sum(o => o.OrderTotalAmt);
}
}
public class SomeReport {
public void GetCustomerInfoBySalesperson(long salespersonID) {
using (var db = new MyDataContext()) {
var q = db.Customers.Where(c => c.SalespersonID == salespersonID)
.Select(c => new { c.Name, c.Address, ThisYearPurchases = c.TotalPurchasesThisYear(db) })
.ToList();
// etc..
}
}
}
显然,这不起作用,因为TotalPurchasesThisYear
没有SQL翻译。但其中的所有内容都有SQL翻译。我不想直接在查询中包含该代码,因为我在很多地方进行相同的计算。我的直觉告诉我这应该用Expression
来完成,但我已经玩过了,并且无法找到正确的语法。
帮助,有人吗? 谢谢!
答案 0 :(得分:0)
好的,我找到了一种方法,但我不确定这是最好的方法:
public class CustomerOrderInfo {
public long CustomerID;
public decimal TotalPurchases;
}
public class Customer {
public static Expression<Func<Customer, CustomerOrderInfo>> GetCustomerOrderInfo() {
return c => new CustomerOrderInfo {
CustomerID = c.ID,
TotalPurchases = c.Orders.Where(o => o.OrderDate.Year == DateTime.Now.Year)
.Sum(o => o.OrderTotalAmt)
};
}
}
public class SomeReport {
public void GetCustomerInfoBySalesperson(long salespersonID) {
using (var db = new MyDataContext()) {
var q = db.Customers
.Join(db.Customers.Select(Customer.GetCustomerOrderInfo()),
c => c.ID, i => i.CustomerID,
(c, i) => new { c.Name, c.Address, i.TotalPurchases })
.ToList();
// etc..
}
}
}
它有效......但底层SQL最终会在嵌套查询上加入,这不是我的理想选择。我希望看到底层的SQL很简单,比如:
select c.Name, c.Address, sum(o.OrderTotalAmt) TotalPurchases
from Customer c
left join [Order] o on o.CustomerID = c.ID
where Year(o.OrderDate) = @year
group by c.Name, c.Address
答案 1 :(得分:0)
List<Parent> myParents = new List<Parent>
{
new Parent()
{
Prop1 = "1",
Prop2 = "2",
Prop3 = "3",
Children = new List<Child>()
{
new Child(){ Prop1 = 1, Prop2 = 2, Prop3 = 3 },
new Child(){ Prop1 = 21, Prop2 = 22, Prop3 = 23 },
new Child(){ Prop1 = 31, Prop2 = 32, Prop3 = 33 }
}
},
};
Expression<Func<Parent, int>> GetChildSum =
p => p.Children.Where(c => c.Prop1 > 0).Sum(o => o.Prop2);
var v = myParents.Where(w => w.Prop1 == "1").Select(p => GetChildSum.Compile().Invoke(p)).ToList();
Console.WriteLine(v.First());
//output is 56