如何通过Linq表达代替谓词?

时间:2017-01-31 02:00:40

标签: c# linq

我在过去几个小时内一直在阅读有关构建我自己的Linq表达式的文章和SO帖子,然后使用这些作为谓词来过滤List或Array中的项目。

这是我到目前为止的一个简单例子:

public class AWDRiskMRASCodeXref
{
    public string RiskSubType { get; set; }
    public string AcordReqCodeInt { get; set; }
    public string MrasReqCodeInt { get; set; }
    public string AcordReqCodePpe { get; set; }
    public string MrasReqCodePpe { get; set; }
    public string AcordReqCodeWeb { get; set; }
    public string MrasReqCodeWebS { get; set; }
} 

然后我将使用Dapper之类的东西从数据库中检索列表;

var items =  conn.Query<AWDRiskMRASCodeXref>("SELECT RiskSubType, AcordReqCodeInt, MrasReqCodeInt, AcordReqCodePpe, MrasReqCodePpe, AcordReqCodeWeb, MrasReqCodeWeb FROM LKUP_AWDRiskMRASCodeXref;").ToList();

var param = Expression.Parameter(typeof(AWDRiskMRASCodeXref), "x");
var member = Expression.Property(param, "AcordReqCodePpe"); //x.AcordReqCodePpe
var constant = Expression.Constant("1004700009");
var body = Expression.Equal(member, constant); //x.AcordReqCodePpe == "1004700009"
var finalExpression = Expression.Lambda<Func<AWDRiskMRASCodeXref, bool>>(body, param); //x => x.AcordReqCodePpe == "1004700009"
finalExpression.Dump();

finalExpression“x =&gt;(x.AcordReqCodePpe ==”1004700009“)”在LinqPad中看起来很棒,但我需要做什么才能使它能够通过以下Linq查询?

var item = items.FirstOrDefault(finalExpression);

谢谢你, 斯蒂芬

2 个答案:

答案 0 :(得分:1)

问题是你已经解决了这个问题。在查询上调用.ToList()时的查询。删除它,以便您的查询读取如下内容:

var item = conn.Query<AWDRiskMRASCodeXref>("SELECT RiskSubType, AcordReqCodeInt, MrasReqCodeInt, AcordReqCodePpe, MrasReqCodePpe, AcordReqCodeWeb, MrasReqCodeWeb FROM LKUP_AWDRiskMRASCodeXref;")
    .FirstOrDefault(finalExpression);

答案 1 :(得分:1)

由于您已经从数据库中提取了数据,因此您需要为表达式执行的操作是编译它并将其传递给FirstOrDefault扩展方法。

var compiledExpression = finalExpression.Compile();
var item = items.FirstOrDefault(compiledExpression);

作为奖励提示,如果您使用.NET Framework 4.6或更高版本。您可以在生成nameof属性时使用member运算符。如果您更改了您的属性名称,它比硬编码字符串要好得多。它看起来像这样:

var member = Expression.Property(param, nameof(AWDRiskMRASCodeXref.AcordReqCodePpe));