LINQ to Entities方法未被识别 - 扩展方法风格

3

这是又一个“LINQ to entities does not recognize the method”问题……但是,下面的代码不是基本上做了完全相同的事情吗?

可行:

var returnData = from x in MyEntities.MyDBSet
                        where x.MyDBSetPrimaryKey == id
                        select new Models.MyModelDTO
                        {
                            MyPropOne = (int)x.MyModel.MyOtherPropOne,
                            MyPropTwo = x.MyOtherPropTwo ?? 0,
                            MyPropThree = x.MyModel.MyOtherPropThree,
                            MyPropFour = x.MyModel.MyOtherPropFour,
                            MyPropFive = x.MyModel.Entity.MyOtherPropFive,
                            MyPropSix = x.MyModel.MyOtherPropSix == null ? 0 : (decimal)x.MyModel.MyOtherPropSix,
                            MyPropSeven = x.MyModel.SomeType.MyOtherPropSeven,
                            MyPropEight = (int)x.MyModel.MyOtherPropEight,
                            MyPropNine = x.MyModel.MyPropNine == null ? 0 : (int)x.MyModel.MyOtherPropNine,
                            MyPropTen = x.MyModel.MyOtherPropTen == null ? 0 : (int)x.MyModel.MyOtherPropTen,
                            MyPropEleven = x.OtherEntity.MyOtherPropEleven,
                            MyPropTwelve = x.MyOtherpropTwelve
                        };

不工作:

相同的任务封装在扩展方法中:

public static MyModelDTO ToModelDTO(this MyModel x)
    {
        return new MyModelDTO()
        {
            MyPropOne = (int) x.MyModel.MyOtherPropOne,
            MyPropTwo = x.MyOtherPropTwo ?? 0,
            MyPropThree = x.MyModel.MyOtherPropThree,
            MyPropFour = x.MyModel.MyOtherPropFour,
            MyPropFive = x.MyModel.Entity.MyOtherPropFive,
            MyPropSix = x.MyModel.MyOtherPropSix == null ? 0 : (decimal) x.MyModel.MyOtherPropSix,
            MyPropSeven = x.MyModel.SomeType.MyOtherPropSeven,
            MyPropEight = (int) x.MyModel.MyOtherPropEight,
            MyPropNine = x.MyModel.MyPropNine == null ? 0 : (int) x.MyModel.MyOtherPropNine,
            MyPropTen = x.MyModel.MyOtherPropTen == null ? 0 : (int) x.MyModel.MyOtherPropTen,
            MyPropEleven = x.OtherEntity.MyOtherPropEleven,
            MyPropTwelve = x.MyOtherpropTwelve
        };
    }

稍后称为:

var returnData = from x in MyEntities.MyDBSet
                        where x.MyDBSetPrimaryKey == id
                        select x.ToModelDto();

导致:
LINQ to Entities does not recognize the method 'MyExtensionMethods.MyModels.MyModelDTO ToModelDTO(API.Models.MyModel)' method, and this method cannot be translated into a store expression.
2个回答

6
当查询提供程序看到这个方法时,它不知道该如何处理它。它无法查看方法的源代码,就像可以查看Expression对象并查看其操作一样。它无法在客户端上对其进行评估,因为它还没有这些项,也无法想到任何SQL将该方法调用转换为的方法。
相反,您应编写一个接受IQueryable并返回另一个IQueryable的方法,如下所示:
public static IQueryable<MyModelDTO> ToModelDTO(this IQueryable<MyModel> query)
{
    return query.Select(x => new MyModelDTO()
    {
        MyPropOne = (int)x.MyModel.MyOtherPropOne,
        MyPropTwo = x.MyOtherPropTwo ?? 0,
        MyPropThree = x.MyModel.MyOtherPropThree,
        MyPropFour = x.MyModel.MyOtherPropFour,
        MyPropFive = x.MyModel.Entity.MyOtherPropFive,
        MyPropSix = x.MyModel.MyOtherPropSix == null ? 0 : (decimal)x.MyModel.MyOtherPropSix,
        MyPropSeven = x.MyModel.SomeType.MyOtherPropSeven,
        MyPropEight = (int)x.MyModel.MyOtherPropEight,
        MyPropNine = x.MyModel.MyPropNine == null ? 0 : (int)x.MyModel.MyOtherPropNine,
        MyPropTen = x.MyModel.MyOtherPropTen == null ? 0 : (int)x.MyModel.MyOtherPropTen,
        MyPropEleven = x.OtherEntity.MyOtherPropEleven,
        MyPropTwelve = x.MyOtherpropTwelve
    });
}

这里的映射仍然被编译成一个Expression,以便查询提供程序可以解析。现在你可以这样做:

var returnData = (from x in MyEntities.MyDBSet
                  where x.MyDBSetPrimaryKey == id
                  select x)
                  .ToModelDTO();

是否可以创建一个扩展方法,该方法可以在 .Select() 方法内部、在新的 MyModelDTO() 初始化器内部执行?我有一些属性,希望能够在 .Select() 方法内部单独执行 WHERE 逻辑... 从本质上讲,在相关实体上执行过滤包含。 - ClearCloud8
@ClearCloud8 这真的取决于你想要做什么具体的事情,所以最好创建一个新问题,其中可以包括一些你想要写的示例。 - Servy

-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接