在Linq到Entities中使用扩展方法

时间:2017-10-23 17:20:17

标签: c# entity-framework linq

代码:

public static IEnumerable<TableRowModel> GetRows()
        {
            var to_ret = db.TableRows.select(x=> new TableRowModel(){
                TableRowId = x.TableRowId,
                Type = x.Type,
                Name = x.Name,
                CreatedAt = x.CreatedAt,
                ModifiedAt = x.ModifiedAt,
                Enums = x.Enums.Select(y => y.ToEnumModel()),
            });
            return to_ret;
        }

public static EnumModel ToEnumModel(this Enum x)
        {
            var to_ret = new EnumModel()
            {
                CFPId = x.CFPId,
                CreatedAt = x.CreatedAt,
                ModifiedAt = x.ModifiedAt,
            };
            return to_ret;
        }

使用GetRows方法时出现以下错误:

  

LINQ to Entities无法识别方法

鉴于错误,我们了解LINQ To Entities无法识别扩展方法ToEnumModel。 我想知道是否有办法解决这个问题? 因此,我不会在ToEnumModel扩展程序中再次重复GetRows代码。

2 个答案:

答案 0 :(得分:1)

在正常情况下,当在EntityFramework中执行像Where这样的操作时,它实际上并没有像在操作可枚举(如List)时那样在内存中执行。相反,它转换为SQL,然后由Db提供程序执行。这意味着执行某些操作(例如在对象上使用扩展方法)不是一种选择,因为转换器无法将这些内容转换为SQL。

最快捷,最简单的解决方案是将您的设备加载到内存中,可以像其他任何可枚举的那样对其进行操作。你可以这样做:

var result = myDbSet.AsEnumerable().Etc()

Etc()此处表示您要运行的所有其他操作。但请注意,这会将所有数据加载到内存中,这在某些情况下可能会非常慢且昂贵。缓解此问题的一种方法是在需要使用扩展方法之前将AsEnumerable() 设置为,从而将尽可能多的操作卸载到提供程序。例如:

var result = myDbSet.Where([condition]).AsEnumerable().Select(item => item.ExtensionMethod());

可能比这更快更轻:

var result = myDbSet.AsEnumerable().Where([condition]).Select(item => item.ExtensionMethod());

答案 1 :(得分:0)

您在EF中使用扩展程序的能力有限,但您仍然可以扩展IQueryable

public static class Extensions
{
    public static IQueryable<MyModelVM> SelectVMs(this IQueryable<MyModel> models)
    {
        return models.Select(x => new MyModelVM { MyModelId = x.MyModelId });
    }
}