我有一个看起来像这样的方法:
public string GetColVal(string aAcctField, bool callM1, bool callM2) { if (callM1) { // create select clause here to select a string column with name // equal to the value of aAcctField from Table1 // Expression> selector = ? return M1(selector); } if (callM2) { // create select clause here to select a string column with name // equal to the value of aAcctField from Table2 // Expression > selector = ? return M2(selector); } }
而且M1()
是这样的:
public string M1(Expression> columnToSelect, string xType) { // other logic string acct = _cntx.Where(c => c.Type == xType) .Select(columnToSelect) .FirstOrDefault(); return acct; }
M2()
也是类似的东西.请注意,这些方法过于简化.而且方法M1()
和M2()
工作完美.我可以这样调用它们:
// MyColumn is a strongly typed column in Table1 string acct = M1(x => x.MyColumn, "some value");
但是,在方法内部GetColVal()
我如何构造select子句?有关的评论selector
将帮助您了解我打算做什么.所以,请继续阅读评论.
我试过这个:
public string GetColVal(string aAcctField, bool callM1, bool callM2) { if (callM1) { // create select clause here to select a string column with name // equal to the value of aAcctField from Table1 Expression> selector = (w) => w.GetType().GetProperty(aAcctField).Name; return M1(selector); } ... }
我得到了例外:
LINQ to Entities无法识别方法'System.Reflection.PropertyInfo GetProperty(System.String)'方法,并且此方法无法转换为存储表达式
我看过这些:
为Select with FirstOrDefault创建动态LINQ表达式
Linq通过变量访问属性
使用C#中的反射从字符串中获取属性值
和许多其他人.
但它们都不是我需要的东西.
基本上你需要使用Expression
类方法一样Expression.Lambda
,Expression.PropertyOrField
等来样订做所需的选择:
static Expression> MemberSelector (string name) { var parameter = Expression.Parameter(typeof(T), "item"); var body = Expression.PropertyOrField(parameter, name); return Expression.Lambda >(body, parameter); }
要支持嵌套属性,请将var body = ...
行更改为
var body = name.Split('.').Aggregate((Expression)parameter, Expression.PropertyOrField);
样品用法:
if (callM1) { return M1(MemberSelector(aAcctField)); } ...