从多个参数组合Linq到实体查询 [英] Composing Linq to Entity Query from multiple parameters

查看:111
本文介绍了从多个参数组合Linq到实体查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个详细的搜索,我正在试图找出如何将我的Linq查询组合到我的实体。



基本上我有可以选择的用户1 *项目列表控件。
我不能包围的部分是以下内容:



我如何动态构建一个 Where AND(field等于该OR字段等于此OR ...)子句
其中项目数是变体。



数据库字段示例内容:'26,21,22,100,164,130'



示例:(想法是能够根据所选项目的数量生成这个数据)

  Offre.Where(o => o.Domain.Contains 26)|| o.Domain.Contains(100))

Offre.Where(o => o.Domain.Contains(26))

Offre.Where(o => o.Domain.Contains(26)|| o.Domain.Contains(100)|| o.Domain.Contains(22))

然后我可以轻松地将生成的查询作为IQueryable,并添加到此对象以构建我的查询。



有人可以指出我的AND(OR .. OR)子句的正确方向吗?

解决方案

要解决此限制,您可以手动构造一个表达式(Source)



C# / p>

  static Expression< Func< TElement,bool>> BuildContainsExpression< TElement,TValue>(

表达式< Func< TElement,TValue>> valueSelector,IEnumerable< TValue>值)

{

if(null == valueSelector){throw new ArgumentNullException(valueSelector); }

if(null == values){throw new ArgumentNullException(values); }

ParameterExpression p = valueSelector.Parameters.Single();

// p => valueSelector(p)== values [0] || valueSelector(p)== ...

if(!values.Any())

{

return e =>假;

}

var equals = values.Select(value =>(Expression)Expression.Equal(valueSelector.Body,Expression.Constant(value,typeof(TValue)) ));

var body = equals.Aggregate< Expression>((accumulate,equal)=> Expression.Or(accumulate,equal));

return Expression.Lambda
}

使用此实用程序方法,

  var query2 = context.Entities.Where(BuildContainsExpression< Entity,int>(e => e.ID,ids)); 

VB.Net


$ b $公共共享函数BuildContainsExpression(对于TElement,TValue)(_
ByVal valueSelector As Expression(Of Func(Of TElement,TValue)),_
ByVal值作为IEnumerable(Of TValue)_
)As Expression(Of Func(Of TElement,Boolean))

'validate arguments
如果IsNothing(valueSelector)然后抛出新的ArgumentNullException( valueSelector)
如果IsNothing(值)然后抛出新的ArgumentNullException(values)

Dim p As ParameterExpression = valueSelector.Parameters.Single()
如果不是值。任何然后
返回_
函数(e)False
结束如果

Dim equals = values.Select(_
函数(v)_
Expression.Equal(valueSelector.Body,Expression.Constant(v,GetType(TValue)))_


Dim body = equals.Aggregate(_
Function积累,相等)_
Expression.Or(accumulate,equal)_


返回Expression.Lambda(Of func(Of TElement,Boolean))(body,p)
End Function

使用此实用程序

  Dim query = m_data。提供

如果(selectedSectors.Count> 0)然后
query = query.Where(BuildContainsExpression(Function(o As Offer)o.Value,selectedSectors))
End If


I'm currently building a detailed search and I am trying to figure out how to compose my Linq query to my Entity.

basically I have users that can select 1* items in a list control. the part I can't wrap my head around is the following:

how can I dynamically build a Where AND( field is equal to this OR field is equal to this OR...) clause where the number of items is variant.

database Domain Field sample content : '26, 21, 22, 100, 164, 130'

Example: (The idea is to be able to generate this depending on the number of items selected)

Offre.Where(o=> o.Domain.Contains("26") || o.Domain.Contains("100") )

Offre.Where(o=> o.Domain.Contains("26") )

Offre.Where(o=> o.Domain.Contains("26") || o.Domain.Contains("100") || o.Domain.Contains("22") )

then I can easily have the resulting query as an IQueryable and add on to this object to build my query.

can someone point me inthe right direction for my AND ( OR .. OR ) clause ?

解决方案

To work around this restriction, you can manually construct an expression (Source)

C#

static Expression<Func<TElement, bool>> BuildContainsExpression<TElement, TValue>(

    Expression<Func<TElement, TValue>> valueSelector, IEnumerable<TValue> values)

{

    if (null == valueSelector) { throw new ArgumentNullException("valueSelector"); }

    if (null == values) { throw new ArgumentNullException("values"); }

    ParameterExpression p = valueSelector.Parameters.Single();

    // p => valueSelector(p) == values[0] || valueSelector(p) == ...

    if (!values.Any())

    {

        return e => false;

    }

    var equals = values.Select(value => (Expression)Expression.Equal(valueSelector.Body, Expression.Constant(value, typeof(TValue))));

    var body = equals.Aggregate<Expression>((accumulate, equal) => Expression.Or(accumulate, equal));

    return Expression.Lambda<Func<TElement, bool>>(body, p);

} 

Using this utility method,

var query2 = context.Entities.Where(BuildContainsExpression<Entity, int>(e => e.ID, ids));

VB.Net

Public Shared Function BuildContainsExpression(Of TElement, TValue)( _
ByVal valueSelector As Expression(Of Func(Of TElement, TValue)), _
ByVal values As IEnumerable(Of TValue) _
   ) As Expression(Of Func(Of TElement, Boolean))

    ' validate arguments
    If IsNothing(valueSelector) Then Throw New ArgumentNullException("valueSelector")
    If IsNothing(values) Then Throw New ArgumentNullException("values")

    Dim p As ParameterExpression = valueSelector.Parameters.Single()
    If Not values.Any Then
        Return _
            Function(e) False
    End If

    Dim equals = values.Select( _
        Function(v) _
            Expression.Equal(valueSelector.Body, Expression.Constant(v, GetType(TValue))) _
    )

    Dim body = equals.Aggregate( _
        Function(accumulate, equal) _
            Expression.Or(accumulate, equal) _
    )

    Return Expression.Lambda(Of Func(Of TElement, Boolean))(body, p)
End Function

Using this utility method

   Dim query = m_data. Offer

   If (selectedSectors.Count > 0) Then
        query = query.Where(BuildContainsExpression(Function(o As Offer) o.Value, selectedSectors))
   End If

这篇关于从多个参数组合Linq到实体查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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