2

使用 Entity Framework 5 时,为什么会这样?

var query = Categories.Select(c => new 
    { 
        Products = c.Products.OrderBy(p => p.Name) 
    });

虽然这不会?

Func<Product, string> selector = p => p.Name;
var query = Categories.Select(c => new 
    { 
        Products = c.Products.OrderBy(selector) 
    });

抛出的异常是:查询运算符“OrderBy”使用了不受支持的重载。

4

3 回答 3

6

query变量名暗示您可能正在使用实体框架、LINQ to SQL 或其他一些基于IQueryable<T>API。你正在传递selectoras Func。底层查询提供程序无法转换Func为 SQL(或任何其他语言,无论您使用什么语言)。

更改selectorto的类型Expression<Func<Product, string>>(其余的可以保持不变,因为 lambda 表达式可以解释为委托或表达式树。这就是您可以使用varlambda 的原因 - 编译器无法判断您是否想要 lambda一个委托或表达式树),看看是否能解决您的问题。你没有提供足够的信息让我 100% 确定,但它应该。OrderBy接受 an的重载Expression应该能够遍历表达式树并将其转换为基础查询。这有点猜测,但我希望它对你有所帮助。

于 2013-07-21T22:30:33.020 回答
0

这是查询工作正常且不会导致问题的工作示例。为了简单起见,我跳过了数据库,直接进入了内存中的对象,这可能就是它对我有用的原因。我认为 Honza 是对的,这是与 ORM 层相关的问题。您可以运行以下示例

这是 linqpad 的示例:

void Main()
{

        var Categories = new List<Category>() { new Category { CategoryName = "CatName", Products = new List<Product>() { new Product { Name = "ProductName1" } } } };

        Func<Product, string> selector = p => p.Name;
        var sb = new StringBuilder();
        var query = Categories.Select(c => new
        {
            Products = c.Products.OrderBy(selector)
        });
        foreach (var x in query)
        {
            sb.AppendLine(x.Products.First().Name);
        }

        Console.WriteLine(sb.ToString());
        Console.Read();


    }


    public class Product
    {
        public string Name { get; set; }
    }

    public class Category
    {
        public string CategoryName { get; set; }
        public List<Product> Products { get; set; }
    }

// 这里定义其他方法和类

这是 Visual Studio 控制台应用程序的版本:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            var Categories = new List<Category>() { new Category { CategoryName = "CatName", Products = new List<Product>() { new Product { Name = "ProductName1" } } } };
        Func<Product, string> selector = p => p.Name;
        var sb = new StringBuilder();
        var query = Categories.Select(c => new
        {
            Products = c.Products.OrderBy(selector)
        });
        foreach (var x in query)
        {
            sb.AppendLine(x.Products.First().Name);
        }

        Console.WriteLine(sb.ToString());
        Console.Read();


    }


    public class Product
    {
        public string Name { get; set; }
    }

    public class Category
    {
        public string CategoryName { get; set; }
        public List<Product> Products { get; set; }
    }
}

}

于 2013-07-22T15:36:15.500 回答
0

制作selectoranExpression<Func<Product, string>>不会直接工作,也不会编译,因为c.Productsis not an IQueryable<T>。它只是一个只实现的集合类型IEnumerable<T>Enumerable.OrderBy不接受表达式作为参数,只接受一个委托。

但是 EF 仍然需要一个表达式,而不是一个委托。诀窍是AsQueryable()在导航集合上使用:

Expression<Func<Product, string>> selector = p => p.Name;
var query = Categories.Select(c => new 
{ 
    Products = c.Products.AsQueryable().OrderBy(selector) 
});
于 2013-07-22T18:02:55.070 回答