5

如何在 linq 查询中使用字符串扩展方法:

public NewsType GetNewsType(string name)
{
   var newsType = db.NewsTypes.FirstOrDefault(x => x.Name.ToFriendlyUrl() ==  
                                              name.ToFriendlyUrl());
   return newsType;
}

上述查询x.Name.ToFriendlyUrl()暂时不允许。有谁知道如何实现它。

4

4 回答 4

3

在 LINQ 查询中确实允许使用扩展方法,而且LINQ 方法本身是作为扩展方法实现的。

然而,在 LINQ-to-SQL 或 LINQ-to-Entities 查询中使用扩展方法(或大多数其他方法)是另一个问题。这些查询实际上并未在 C# 代码中运行,但它们被视为转换为 SQL 的表达式。IE

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());
于 2013-08-20T10:14:52.200 回答
1

这个

var newsType = db.NewsTypes.FirstOrDefault(
          x => x.Name.ToFriendlyUrl() == name.ToFriendlyUrl());

不能在实体框架中完成。ToFriendlyUrl是一种扩展方法。它是在“客户端”计算机中的东西。查询将在 SQL 服务器上执行。SQL 服务器没有ToFriendlyUrl功能。

“标准”解决方案是保存在名为FriendlyName的预计算版本的第二列中ToFriendlyUrl(),因此您的查询变为:

var friendlyName = name.ToFriendlyUrl();
var newsType = db.NewsTypes.FirstOrDefault(
          x => x.FriendlyName == friendlyName);
于 2013-08-20T10:11:30.127 回答
1

假设这NewsTypesIQueryable一个实体框架无法将您的扩展方法转换为 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服务器返回的所有行都拉到客户端,因此可能会非常昂贵。

于 2013-08-20T10:14:35.547 回答
0

而是尝试这样

public NewsType GetNewsType(string name)
{
   var newsType = db.NewsTypes.FirstOrDefault(x => x.Name == name).ToFriendlyUrl();
   return newsType;
}
于 2013-08-20T10:10:23.477 回答