如何动态创建一个表达式<func <t,object =“” >>

时间:2018-11-14 02:57:49

标签: c# linq reflection func

我有一个这样的班级:

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string LOANIDBPM { get; set; }
    public string REPORTTYPE { get; set; }
}

我有一个学生名单, 我想按LOANIDBPMREPORTTYPE过滤列表中的某些学生。

通常,这是代码(使用linq)

public void GetListStudent(List<Student> listStudent)
{
    listStudent = listStudent.Where(x => x.LOANIDBPM == "MIKEN" && x.REPORTTYPE == "DX").ToList();
}

但是,由于某些原因,我无法明确显示“列表”, 我的解决方案如下:

public void GetListStudent(object[] listStudent)
{
    ParameterExpression param = Expression.Parameter(listStudent.First().GetType(), nameof(listStudent));
    Expression propLoanBPM = Expression.Property(param, "LOANIDBPM");
    Expression<Func<string>> loanIdLampda = () => "MIKEN";
    Expression searchLoanBPM = Expression.Equal(propLoanBPM, loanIdLampda.Body);

    Expression propReportType = Expression.Property(param, "REPORTTYPE");
    Expression<Func<string>> reportTypeLampda = () => "DX";

    Expression searchReportType = Expression.Equal(propReportType, reportTypeLampda.Body);

    Expression searchFinal = Expression.And(searchLoanBPM, searchReportType);


    Expression<Func<???, bool>> lampda = Expression.Lambda<Func<???, bool>>(searchFinal, param);

    listStudent = listStudent.Where(lampda).ToArray();
}

上面的代码有两个问题:

1:我不知道Expression Func中学生的类型, 我不能这样使用:

Expression<Func< listStudent.First().GetType(), bool>> lampda = Expression.Lambda<Func< listStudent.First().GetType(), bool>>(searchFinal, param);

2:在Where方法中,需要IQueryable,但在我的代码中是Expression Func。

对不起,我的英语。 非常感谢

1 个答案:

答案 0 :(得分:0)

您的第一个示例无法编译,因为listStudent是一个列表,而LINQ通常将返回某种IEnumerable。您需要添加ToList()

public void GetListStudent(List<Student> listStudent)
{
    listStudent = listStudent
        .Where
        (
            x => x.LOANIDBPM == "MIKEN" && x.REPORTTYPE == "DX"
        )
        .ToList();  //<-- add this
}

您的第二个示例不起作用,因为c#不知道您的对象数组实际上是学生列表。您可以使用Cast<>()方法告诉它。完成后,您需要转换回数组,因此请在末尾添加ToArray()

public void GetListStudent(object[] listStudent)
{
    listStudent = listStudent
        .Cast<Student>()  //<-- add this
        .Where
        (
            x => x.LOANIDBPM == "MIKEN" && x.REPORTTYPE == "DX"
        )
        .ToArray();       //<-- and this
}

如果只知道某些对象是学生,则可以使用OfType<>()来过滤掉它们。

public void GetListStudent(object[] listStudent)
{
    listStudent = listStudent
        .OfType<Student>()  //<-- add this
        .Where
        (
            x => x.LOANIDBPM == "MIKEN" && x.REPORTTYPE == "DX"
        )
        .ToArray();       //<-- and this
}

如果您完全不知道这些对象是什么,但是可以肯定它们具有LOANIDBPMREPORTTYPE属性,我想您可以使用dynamic

public void GetListStudent(List<dynamic> listStudent)
{
    listStudent = listStudent
        .Where
        (
            x => x.LOANIDBPM == "MIKEN" && x.REPORTTYPE == "DX"
        )
        .ToList();
}
相关问题