我在过去几个小时内一直在阅读有关构建我自己的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);
谢谢你, 斯蒂芬
答案 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));