在 LINQ to Entities 中使用自定义方法/扩展方法的解决方法 [英] Workarounds for using custom methods/extension methods in LINQ to Entities

查看:15
本文介绍了在 LINQ to Entities 中使用自定义方法/扩展方法的解决方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我定义了一个执行数据库交互的 GenericRepository 类.

 protected GenericRepository rep = new GenericRepository();

在我的 BLL 课程中,我可以像这样查询数据库:

公开列表<专辑>GetVisibleAlbums(int accessLevel){return rep.Find(a => a.AccessLevel.BinaryAnd(accessLevel)).ToList();}

BinaryAnd 是一种扩展方法,它逐位检查两个 int 值.例如AccessLevel=5 => AccessLevel.BinaryAnd(5)AccessLevel.binaryAnd(1) 都返回 true.

但是我不能在我的 LINQ 查询中使用这个扩展方法.我收到如下运行时错误:
LINQ to Entities 无法识别方法 'Boolean BinaryAnd(System.Object, System.Object)' 方法,并且该方法无法转换为存储表达式.

还尝试将其更改为自定义方法,但没有成功.有哪些解决方法?

我是否应该获取所有专辑,然后通过 foreach 循环对它们进行迭代并选择那些与 AccessLevels 匹配的专辑?

解决方案

您只能使用 在使用实体框架和 IQueryable 上的查询时为您的 EF 提供程序定义的核心扩展方法和 CLR 方法.这是因为查询被直接转换为 SQL 代码并在服务器上运行.

您可以流式传输整个集合(使用 .ToEnumerable()),然后在本地查询,或将其转换为可由您的提供者直接转换为 SQL 的方法.

话虽如此,支持基本的按位运算:><块引用>

当操作数是数字类型时,按位 AND、OR、NOT 和 XOR 运算符也映射到规范函数.

因此,如果您将其重写为不使用方法,而直接对值进行按位运算,则应该可以正常工作.请尝试以下操作:

公开列表<专辑>GetVisibleAlbums(int accessLevel){return rep.Find(a => (a.AccessLevel & accessLevel > 0)).ToList();}

(我不确定您当前的扩展方法究竟是如何工作的 - 以上将检查是否有任何标志返回 true,这似乎与您的陈述相符...)

I have defined a GenericRepository class which does the db interaction.

 protected GenericRepository rep = new GenericRepository();

And in my BLL classes, I can query the db like:

public List<Album> GetVisibleAlbums(int accessLevel)
{
    return rep.Find<Album>(a => a.AccessLevel.BinaryAnd(accessLevel)).ToList();  
}  

BinaryAnd is an extension method which checks two int values bit by bit. e.g. AccessLevel=5 => AccessLevel.BinaryAnd(5) and AccessLevel.binaryAnd(1) both return true.

However I cannot use this extension method in my LINQ queries. I get a runtime error as follows:
LINQ to Entities does not recognize the method 'Boolean BinaryAnd(System.Object, System.Object)' method, and this method cannot be translated into a store expression.

Also tried changing it to a custom method but no luck. What are the workarounds?

Should I get all the albums and then iterate them through a foreach loop and pick those which match the AccessLevels?

解决方案

You can only use the core extension methods and CLR methods defined for your EF provider when using Entity Framework and queries on IQueryable<T>. This is because the query is translated directly to SQL code and run on the server.

You can stream the entire collection (using .ToEnumerable()) then query this locally, or convert this to a method that is translatable directly to SQL by your provider.

That being said, basic bitwise operations are supported:

The bitwise AND, OR, NOT, and XOR operators are also mapped to canonical functions when the operand is a numeric type.

So, if you rewrite this to not use a method, and just do the bitwise operation on the value directly, it should work as needed. Try something like the following:

public List<Album> GetVisibleAlbums(int accessLevel)
{
    return rep.Find<Album>(a => (a.AccessLevel & accessLevel > 0)).ToList();  
}

(I'm not sure exactly how your current extension method works - the above would check to see if any of the flags come back true, which seems to match your statement...)

这篇关于在 LINQ to Entities 中使用自定义方法/扩展方法的解决方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆