绕过LINQ to Entities的方法无法识别该方法

本文关键字:方法 识别 LINQ to Entities 绕过 | 更新日期: 2023-09-27 18:19:25

我有一个方法,我一直在用它来对付IEnumerable,没问题。然而,我也想开始使用它来对付IQueryable。然而,我目前拥有它的方式无法工作,因为它试图对数据库执行我的方法。

情况如下。如果从中选择的值为null,则我希望所选对象的属性为null,如果存在,则希望该属性的Id和Name为null。例如:

var foos = FooRepository.All().Select(s => new FooBrief()
{
    Id = s.Id,
    Customer = SimpleData.To(s.Customer, m => m.Id, m => m.Name)
});

其中SimpleData.To看起来像:

public class SimpleData
{
    public int Id { get; set; }
    public string Name { get; set; }
    public static SimpleData To<T>(T t, Func<T, int> id, Func<T, string> name) where T : class
    {
        if (t != null)
        {
            return new SimpleData { Id = id(t), Name = name(t) };
        }
        return null;
    }
}

有没有什么方法可以在允许它对数据库执行的同时获得这种行为?

注意:由于代码中其他地方的原因,我无法使用.ToList()。稍后我可能会添加额外的过滤功能

绕过LINQ to Entities的方法无法识别该方法

最简单的方法就是使用AsEnumerable:在数据库外部执行选择

var foos = FooRepository.All()
                        .Select(x => new { Id = x.Id,
                                           CustomerId = x.Customer.Id,
                                           CustomerName = x.Name })
                        .AsEnumerable()
                        .Select(s => new FooBrief {
                                   Id = s.Id,
                                   Customer = new SimpleData { 
                                       Id = s.CustomerId,
                                       Name = s.CustomerName
                                   }
                                });

第一个Select只是为了确保数据库查询只提取所需的字段。如果你真的还想使用你的SimpleData.To方法:

// Outdented to avoid scrolling
var foos = FooRepository.All()
    .Select(x => new { Id = x.Id,
                       CustomerId = x.Customer.Id,
                       CustomerName = x.Name })
    .AsEnumerable()
    .Select(s => new FooBrief {
               Id = s.Id,
               Customer = SimpleData.To(s,
                                        s => s.CustomerId,
                                        s => s.CustomerName)
            });