2017-04-06 63 views
0

我生成使用LINQ表達一個where條件。LINQ表達AndAlso與空類型

我的實體如下;

public class Sample 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public int AnotherId { get; set; } 
    public int? RelationId { get; set; } 
} 

我不得不篩選基於2個鍵,即AnotherIdRelationId.RelationId(可選)的數據。所以在我的方法參數relationId可能不會更新和爲0

在此基礎上,我需要生成一個表達式:

Expression<Func<Sample, bool>> condition = x => x.AnotherId == anotherId; 
if (relationId > 0) 
{ 
    Expression<Func<Sample, bool>> additionalCondition = x => x.RelationId == relationId; 
    condition = Expression.Lambda<Func<Sample, bool>>(Expression.AndAlso(condition, additionalCondition), condition.Parameters); 
} 

在這裏我得到了在AndAlso聲明以下異常:

二進制運算符AndAlso未對該類型 'System.Func``2 [樣品,System.Boolean]' 和 'System.Func`2 [樣品,System.Boolean]' 限定。

請幫我糾正我的問題。

+0

檢查[此](http://stackoverflow.com/a/13968172/1559611)鏈路 –

+0

我認爲'條件= Expression.Lambda > (Expression.AndAlso(condition.Body,additionalCondition.Body),condition.Parameters);!'應該工作 –

+1

難道只是'x.AnotherId == anotherId &&(relationId> 0 || x.RelationId == relationId)'? –

回答

1

這應該工作...

if(!(relationId>0)) 
{ 
    Expression<Func<Sample, bool>> condition = x => x.AnotherId == anotherId; 
} else { 
    Expression<Func<Sample, bool>> condition = x => x.AnotherId == anotherId && x.RelationId == relationId; 
} 

或...

Expression<Func<Sample, bool>> condition = (!(relationId>0)) 
    ? x => x.AnotherId == anotherId 
    : x => x.AnotherId == anotherId && x.RelationId == relationId; 

雖然當我看到有人問如何做到這一點大部分時間,這是因爲他們真正想要做的這樣的:

var query = something.Where(x=>x.AnotherId == anotherId); 
if (relationId>0) 
{ 
    query = query.Where(x=>x.RelationId == relationId); 
} 
+0

感謝將檢查 – Akhil

+0

呀,鏈接'Where'是典型的好辦法。 –

0

正如其他人可能已經指出的那樣,最簡單的方法是

x => x.AnotherId == anotherId && (relationId <= 0 || x.RelationId == relationId); 

但是,如果你仍然想使用Expression,也許對未來的證明,你需要定義parameterproperty

另外,你需要轉換你的anotherIdNullable int

例子:

ParameterExpression param = Expression.Parameter(typeof(Sample), "x"); 
var anotherIdParam = Expression.Property(param, "anotherId"); 
var condition = Expression.Equal(anotherIdParam, Expression.Constant(anotherId)); 

if (relationId > 0) 
{ 
    var relationIdParam = Expression.Property(param, "relationId"); 
    var additionalCondition = Expression.Equal(relationIdParam, Expression.Convert(Expression.Constant(relationId), typeof(Nullable<int>))); 
    condition = Expression.AndAlso(condition, additionalCondition); 
} 

var finalExpression = Expression.Lambda<Func<Sample, bool>>(condition, param); 
0

簽出LinqPad上的代碼的工作版本,用Visual Studi替換Dump調用O,因爲這是特定於LinqPad

void Main() 
{ 
    // Create Sample Data 
    List<Sample> list = Sample.CreateList(); 

    // Filtering Constants 
    const int anotherId = 1; 
    const int relationId = 1; 

    // Create Parameter Expression 
    ParameterExpression parameterType = Expression.Parameter(typeof(Sample), "object"); 

    // Fetch AnotherId Property 
    MemberExpression typeColumnAnotherId = Expression.Property(parameterType, "anotherId");  

    // Create AnotherId Constant Expression 
    ConstantExpression constantAnotherId = Expression.Constant(anotherId, typeof(int)); 

    // Create Binary Expression 
    BinaryExpression body = Expression.Equal(typeColumnAnotherId, constantAnotherId); 

    // Assign to Result Expression 
    Expression resultExpression = body; 

    if (relationId > 0) 
    { 
     // RelationId Expressions - Member 
     MemberExpression typeColumnRelationId = Expression.Property(parameterType, "relationId"); 

     // RelationId Expressions - Constant 
     ConstantExpression constantRelationId = Expression.Constant(relationId, typeof(int?)); 

     // RelationId Expressions - Binary Expression 
     BinaryExpression body1 = Expression.Equal(typeColumnRelationId, constantRelationId); 

     // Combiner using AndAlso 
     resultExpression = Expression.AndAlso(body, body1); 
    } 

    // Create Result Expression Tree and Compile 
    var resultExpressionTree = Expression.Lambda<Func<Sample, bool>>(resultExpression, parameterType); 

    var resultFunc = resultExpressionTree.Compile(); 

    var finalResult = list.Where(resultFunc); 
    finalResult.Dump(); 
} 

public class Sample 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public int AnotherId { get; set; } 
    public int? RelationId { get; set; } 

    public static List<Sample> CreateList() 
    { 
     var sampleList = new List<Sample>(); 

     for (int i = 0; i < 10; i++) 
     { 
      sampleList.Add(new Sample 
      { 
      Id = i, 
      Name = i.ToString(), 
      AnotherId = i, 
      RelationId = i 
      }); 
     } 

     return sampleList; 

    } 
}