LINQ Element Expression Obtained as a Column

Hello,

I am using LINQ and EF with C # 4.0. I dragged the main ELMAH table into EF (created and saved many times). Everything works as expected.

But they tried to be too ambitious and needed a little help - I'm trying to get the column name from an expression that is passed as a variable.

I want it:

Go to: x => x.ErrorId

and get: "ErrorId"

public void GetColumnName(Expression<Func<T, object>> property) { // The parameter passed in x=>x.Message // Message works fine (probably because its a simple string) using: string columnName = (property.Body as MemberExpression).Member.Name; // But if I attempt to use the Guid or the date field then it // is passed in as x => Convert(x.TimeUtc) // As a result the above code generates a NullReference exception // ie {"Object reference not set to an instance of an object."} // What is the correct code here to extract the column name generically? // Ideally in a way that won't bite me again in the future. } 

Thanks for the help! Dan.

+6
source share
1 answer

If you also need to decompose simple (or almost simple) expressions, you will need additional work to handle various situations. Here are a few startup codes that handle some common cases:

 string GetColumnName<T,TResult>(Expression<Func<T,TResult>> property) { var member = GetMemberExpression(property.Body); if (member == null) throw new ArgumentException("Not reducible to a Member Access", "property"); return member.Member.Name; } MemberExpression GetMemberExpression(Expression body) { var candidates = new Queue<Expression>(); candidates.Enqueue(body); while (candidates.Count > 0) { var expr = candidates.Dequeue(); if (expr is MemberExpression) { return ((MemberExpression)expr); } else if (expr is UnaryExpression) { candidates.Enqueue(((UnaryExpression)expr).Operand); } else if (expr is BinaryExpression) { var binary = expr as BinaryExpression; candidates.Enqueue(binary.Left); candidates.Enqueue(binary.Right); } else if (expr is MethodCallExpression) { var method = expr as MethodCallExpression; foreach (var argument in method.Arguments) { candidates.Enqueue(argument); } } else if (expr is LambdaExpression) { candidates.Enqueue(((LambdaExpression)expr).Body); } } return null; } 

What produces the output, for example:

 GetColumnName((x) => xX): "X" GetColumnName((x) => xX + 2): "X" GetColumnName((x) => 2 + xX): "X" GetColumnName((x) => -xX): "X" GetColumnName((x) => Math.Sqrt(xY)): "Y" GetColumnName((x) => Math.Sqrt(Math.Abs(xY))): "Y" 
+6
source

Source: https://habr.com/ru/post/889981/


All Articles