我的代码如下:
using (DBContext context = new DBContext())
{
myCollection = context.Items.Where(i => i.Type == 1).OrderBy(k => k.Name).Select(w => new
{
Alias = w.Name + string.Format("{0}", w.Id),
Name = w.Name
}).ToArray();
}
在运行时,我在尝试连接字符串并尝试将整数w.Id转换为字符串时遇到错误。
错误说:
Linq to entities无法识别方法string.Format
也不支持串联符号'+'。
我通过引入AsEnumerable来解决这个问题:
using (DBContext context = new DBContext())
{
myCollection = context.Items.AsEnumerable().Where(i => i.Type == 1).OrderBy(k => k.Name).Select(w => new
{
Alias = w.Name + string.Format("{0}", w.Id),
Name = w.Name
}).ToArray();
}
但我想知道这是否是最佳解决方案,还是有其他方式更适合这样做。想法?
答案 0 :(得分:15)
EF无法将String.Format
转换为SQL,但它处理字符串连接没有问题。使用SqlFunctions.StringConvert
代替String.Format
将数字转换为服务器端的字符串:
Select(w => new {
Alias = w.Name + SqlFunctions.StringConvert((double)w.Id),
Name = w.Name
})
它生成类似
的内容SELECT
[Extent1].[Name] + STR( CAST( [Extent1].[Id] AS float)) AS [C1],
[Extent1].[Name] AS [Name]
FROM [dbo].[Items] AS [Extent1]
更新:因此,您使用的EF提供程序不支持此转换(SQL CE提供程序无法将此查询转换为SQL)您只剩下一个选项 - 将计算移动到客户端,就像您已经完成的那样。
答案 1 :(得分:15)
您的代码的一个优化是在AsEnumerable()
方法之后使用Where
。如果不是,则从存储返回每个实体,并使用LINQ to Objects检查整个表。通过对代码的这种简单修改,您可以在sql上运行where子句并从存储中检索较少的记录。一般规则是首先放置由LINQ提供程序实现的任何查询子句。
using (DBContext context = new DBContext())
{
myCollection = context.Items.Where(i => i.Type == 1)
.AsEnumerable().OrderBy(k => k.Name).Select(w => new
{
Alias = w.Name + string.Format("{0}", w.Id),
Name = w.Name
}).ToArray();
}