I have a method which looks something like this:
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<Func<Table1, string>> 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<Func<Table2, string>> selector = ?
return M2(selector);
}
}
And M1()
is something like this:
public string M1(Expression<Func<Table1, string>> columnToSelect, string xType)
{
// other logic
string acct = _cntx.Where(c => c.Type == xType)
.Select(columnToSelect)
.FirstOrDefault();
return acct;
}
M2()
is also something similar. Please note that the methods are over-simplified. And the methods M1()
and M2()
work perfectly. I can invoke them this way:
// MyColumn is a strongly typed column in Table1
string acct = M1(x => x.MyColumn, "some value");
But, inside the method GetColVal()
how do I construct the select clauses? The comments regarding selector
will help you understand what I intend to do. So, please go ahead and read the comment.
I have tried this:
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<Func<Table1, string>> selector = (w) => w.GetType().GetProperty(aAcctField).Name;
return M1(selector);
}
...
}
and I get the exception:
LINQ to Entities does not recognize the method 'System.Reflection.PropertyInfo GetProperty(System.String)' method, and this method cannot be translated into a store expression
I have looked at these:
but none of them is quite something like what I need.
Basically you need to use the Expression
class methods like Expression.Lambda
, Expression.PropertyOrField
etc. to build the desired selector like:
static Expression<Func<T, TValue>> MemberSelector<T, TValue>(string name)
{
var parameter = Expression.Parameter(typeof(T), "item");
var body = Expression.PropertyOrField(parameter, name);
return Expression.Lambda<Func<T, TValue>>(body, parameter);
}
To support nested properties, change var body = ...
line to
var body = name.Split('.').Aggregate((Expression)parameter, Expression.PropertyOrField);
Sample usage:
if (callM1)
{
return M1(MemberSelector<Table1, string>(aAcctField));
}
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With