LinQ OrderBy anonymous value
本文关键字:value anonymous OrderBy LinQ | 更新日期: 2023-09-27 18:02:13
下面的代码不能运行:
var x = from user in db.tblUsers
select new
{
user.Id,
user.FirstName,
user.LastName,
NumOfWins = SqlFactory.GetNumberOfWinsByUser(user.Id)
};
TblBindingSource.DataSource = x.OrderByDescending(user => user.NumOfWins);
dataGridView1.DataSource = TblBindingSource.DataSource; //<-- fail here
错误:方法'Int32 GetNumberOfWinsByUser(Int32)'不支持翻译成SQL
我知道SqlFactory.GetNumberOfWinsByUser(user.Id)
返回一个好值。有人能帮我一下吗?
答案在错误中。很明显,您正在使用linq提供程序,例如将linq转换为SQL的实体框架。它不能将SqlFactory.GetNumberOfWinsByUser(user.Id)方法转换为SQL语句。如果你想使用它,你必须这样做:
from user in db.tblUsers.ToList()
select new { user.Id, user.FirstName, user.LastName, NumOfWins = SqlFactory.GetNumberOfWinsByUser(user.Id) };
这将强制它首先将数据读取到内存中,然后在select语句中应用转换。
有一种方法可以将这种函数嵌入到Linq2SQL查询中,前提是您的函数(在您的情况下为GetNumberOfWinsByUser()
)本身可以编写为Expression<Func<>>
类型,其中表达式可以由提供者转换为SQL
这是由Tomáš Petříček设计并在他的博客中描述的:
http://tomasp.net/blog/dynamic-linq-queries.aspx它解释了如何定义表达式:
Expression<Func<Nwind.Product, decimal?>> calcPrice =
(p) => p.UnitPrice * 1.19m;
,然后嵌入到Linq to SQL查询中:
var q =
from p in db.Products.ToExpandable()
where calcPrice.Expand(p) > 30.0m
select new {
p.ProductName,
OriginalPrice = p.UnitPrice,
ShopPrice = calcPrice.Expand(p) };
使用他创建的扩展方法ToExpandable()
(可以下载代码)。
这允许整个查询被解析成SQL并在DB服务器上执行,而不必将任何部分结果集具体化到内存中。它应该非常高效,可以处理非常复杂的查询。我通常发现,将逻辑封装到像这样的表达式中可以使代码简单,并且具有良好的可重用性。
我在一个项目中广泛使用它,它工作得很好。但是,您需要很好地掌握表达式。