在LINQ to Entities中使用自定义方法/扩展方法的变通方法

Kam*_*yar 9 linq extension-methods linq-to-entities c#-4.0

我已经定义了一个GenericRepository类来执行db交互.

 protected GenericRepository rep = new GenericRepository();
Run Code Online (Sandbox Code Playgroud)

在我的BLL类中,我可以查询db,如:

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

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

但是我不能在LINQ查询中使用此扩展方法.我得到一个运行时错误如下:
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.

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

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

小智 8

我意识到这已经有了一个公认的答案,我只是想我会发布这个以防万一有人想尝试编写一个LINQ表达式拦截器.

所以......这就是我为制作可翻译的自定义扩展方法所做的工作:代码示例

我不认为这是一个完成的解决方案,但它应该为任何勇敢的人看到它完成提供一个良好的起点.


Ree*_*sey 7

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

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

话虽如此,支持基本的按位运算:

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

因此,如果您重写此方法以不使用方法,并且只是直接对值执行按位操作,则应该根据需要进行操作.尝试以下内容:

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

(我不确定你当前的扩展方法是如何工作的 - 上面会检查是否有任何标志返回true,这似乎与你的语句相符......)