0

I am generating one where condition using a LINQ expression.

My entity is as follows;

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

I have to filter data based on 2 keys, namely AnotherId and RelationId.RelationId (optional). So in my method parameter relationId may not update and be 0.

Based on this I need to generate an expression:

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);
}

Here I got the following Exception in the AndAlso statement:

The binary operator AndAlso is not defined for the types 'System.Func``2[Sample,System.Boolean]' and 'System.Func`2[Sample,System.Boolean]'.

Please help me to correct my issue.

g t
  • 7,287
  • 7
  • 50
  • 85
Akhil
  • 1,918
  • 5
  • 30
  • 74

2 Answers2

1

This should work...

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;
}

or...

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

Although most times when I see someone asking how to do this, it is because they are really trying to do this:

var query = something.Where(x=>x.AnotherId == anotherId);
if (relationId>0)
{
  query = query.Where(x=>x.RelationId == relationId);
}
Robert McKee
  • 21,305
  • 1
  • 43
  • 57
0

As others might have pointed out, the simplest way is

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

But if you still want to use Expression, maybe for future proof, you need to define the parameter and the property

Also, you need to convert your anotherId to Nullable int

Example:

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);
Kien Chu
  • 4,735
  • 1
  • 17
  • 31