LINQ表达式和Nullable类型

时间:2017-04-06 06:19:42

标签: c# linq

我使用LINQ表达式生成一个where条件。

我的实体如下;

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未定义类型&#39; System.Func``2 [Sample,System.Boolean]&#39;和&#39; System.Func`2 [Sample,System.Boolean]&#39;。

请帮我纠正我的问题。

2 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分:0)

正如其他人可能指出的那样,最简单的方法是

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

但是,如果您仍想使用Expression,可能为了将来的证明,您需要定义parameterproperty

此外,您需要将anotherId转换为Nullable 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);