使用子类的lambda表达式

时间:2018-09-20 10:58:23

标签: c# lambda asp.net-core-2.1

我有以下情况:

public class BaseClass
{
public string Field1 { get; set; }
public string Field2 { get; set; }
public string Field3 { get; set; }    
}

public class Product: BaseClass
{
/* Some methods*/
}

public class Country: BaseClass
{
/* Some methods*/
}

public class MyCustomClass
{
public Product Product { get; set; }
public Country Country { get; set; }    
}

我想创建一个表达式列表,以后用它来查询我的MyCustomClass示例

var listOfExpressions= new List<Expression<Func<MyCustomClass, bool>>>();

if (x == 1)
    listOfExpressions.Add(x => x.Product.Field1 == "Fruit")
/*.
  .
  .*/
if (y == 2)
    listOfExpressions.Add(x => x.Country.Field2 == "Western")
} 

现在,对于这些Ifs来说,这看起来确实很丑陋,我更愿意在BaseClass中使用一个方法,为此您需要传递int{1,2,3})并将其返回给我表达。问题是我需要具有类型<MyCustomClass, bool>的表达式,但是在我的BaseClass中我不能直接得到它,有没有一种方法可以在不使代码过于复杂的情况下实现呢?

我正在考虑这样的事情:

public class BaseClass
{
public string Field1 { get; set; }
public string Field2 { get; set; }
public string Field3 { get; set; }    

protected Expression<Func<BaseClass, bool>> GetExpression(int key, string value)
{
        switch (key)
        {
            case 1:
                return x => x.Field1 == value;
            case 2:
                return x => x.Field2 == value;
            case 3:
                return x => x.Field3 == value;
        }
}

现在,我对如何在Expression<Func<BaseClass, bool>>中使用Expression<Func<MyCustomClass, bool>>感到困惑。

编辑:表达式的目的:

我想构造一个表达式列表,以便以后使用它通过实体框架核心查询数据库。示例:

    var query = DbContext.MyCustomClass.AsQueryable();

    foreach (var expression in listOfExpressions)
    {
        query = query.Where(expression);
    }

1 个答案:

答案 0 :(得分:0)

您可以自己构建表达式。只需向GetExpression添加另一个参数:

public static Expression<Func<MyCustomClass, bool>> GetExpression(
    string derrivedName, // "Product" or "Country"
    int fieldId,
    string value)
{
    var x = Expression.Parameter(typeof(MyCustomClass), "x");
    var lambda = Expression.Lambda<Func<MyCustomClass, bool>>(
        Expression.Equal(
            Expression.Constant(value),
            Expression.PropertyOrField(
                Expression.PropertyOrField(x, derrivedName),
                $"Field{fieldId}")
            ), 
            x);

    return lambda;
}

现在,您可以像这样使用它:

var exp3 = GetExpression("Product", 1, "Fruit");

此行将创建一个表达式x => ("Fruit" == x.Product.Field1)