如何在linq查询中使用字符串扩展方法:
public NewsType GetNewsType(string name)
{
var newsType = db.NewsTypes.FirstOrDefault(x => x.Name.ToFriendlyUrl() ==
name.ToFriendlyUrl());
return newsType;
}
上次查询x.Name.ToFriendlyUrl()
不允许。有谁知道如何实现它。
答案 0 :(得分:1)
此
var newsType = db.NewsTypes.FirstOrDefault(
x => x.Name.ToFriendlyUrl() == name.ToFriendlyUrl());
无法在Entity Framework中完成。 ToFriendlyUrl
是一种扩展方法。这是“客户端”计算机中的东西。查询将在SQL服务器上执行。 SQL服务器没有ToFriendlyUrl
函数。
“标准”解决方案是将名为FriendlyName
的第二列保存为ToFriendlyUrl()
的预先计算版本,以便您的查询变为:
var friendlyName = name.ToFriendlyUrl();
var newsType = db.NewsTypes.FirstOrDefault(
x => x.FriendlyName == friendlyName);
答案 1 :(得分:1)
假设NewsTypes
是IQueryable
,这是实体框架无法将扩展方法转换为SQL的结果(应该如何?)。除非您可以将谓词重写为Entity Framework可以转换为SQL的内容,否则您必须执行查询客户端:
public NewsType GetNewsType(string name)
{
var newsType = db.NewsTypes.AsEnumerable().FirstOrDefault(x => x.Name.ToFriendlyUrl() == name.ToFriendlyUrl());
return newsType;
}
注意AsEnumerable()
之前添加了FirstOrDefault
的方法。不幸的是,这可能会将NewsTypes
返回的所有行从服务器拉到客户端,因此可能会非常昂贵。
答案 2 :(得分:1)
LINQ查询确实允许使用扩展方法,而且LINQ methods本身也是作为扩展方法实现的。
然而,在LINQ-to-SQL或LINQ-to-Entities查询中使用扩展方法(或大多数其他方法)是另一个问题。这些查询实际上并不在C#代码中运行,但它们被视为转换为SQL的表达式。即。
db.News.Where(x => x.Published).Select(x => x.Name)
被翻译为SQL语句
Select Name
From News
Where Published = 1
并将结果返回给C#代码。
由于无法将ToFriendlyUrl()
方法转移到SQL,因此您的代码会抛出错误。
基本上,你有两个解决方案/解决方法。一种是将调用转换为可以转换为SQL的形式,例如如果ToFriendlyUrl()
方法只是:
public static string ToFriendlyURL(this string value)
{
return value.ToLower();
}
您可以在LINQ调用中内联该代码,这样可行。但是,如果方法更复杂,那么您唯一的解决方案就是从基础中获取数据,然后在C#端处理它:
var newsTypeQuery = db.NewsTypes.Where(x => // other conditions, if any);
var newsTypes = newsTypes.ToList(); //forces execution of the query
// the result is now a C# list
var newsType = newsTypes.FirstOrDefault(x =>
x.Name.ToFriendlyUrl() == name.ToFriendlyUrl());
答案 3 :(得分:0)
相反尝试这样
public NewsType GetNewsType(string name)
{
var newsType = db.NewsTypes.FirstOrDefault(x => x.Name == name).ToFriendlyUrl();
return newsType;
}