LINQ成员表达越来越列名

编程入门 行业动态 更新时间:2024-10-24 15:21:20
本文介绍了LINQ成员表达越来越列名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

您好,

我使用LINQ和EF与C#4.0。 口已经拖了基本表ELMAH到EF(建成并挽救了很多很多次)。 的所有工作正如人们所期望

但试图过于雄心勃勃,需要一些帮助 - 我想从获得列名。传递中作为变量表达式

我想是这样的:

在传递:X => x.ErrorId

和获取:ErrorID中

公共无效GetColumnName(表达式来; Func键< T,对象>>物业) { // x中传递的参数=> x.Message //消息使用正常工作(可能是因为它的一个简单的字符串)串COLUMNNAME =(property.Body为MemberExpression).Member.Name; //但是,如果我尝试使用GUID或日期字段则 //在为x =>通过; CONVERT(x.TimeUtc) //因此上面的代码生成一个例外NullReference //即{未将对象引用设置到对象的实例。} //什么是这里的正确的代码一般提取列名? //理想地在不会再次咬我在未来的一种方式。 }

感谢您的帮助! 丹

解决方案

如果您还需要分解简(或几乎简单)的表达式,你需要一些额外的跑腿来处理不同的情况。这里是处理一些常见的情况下,一些启动代码:

字符串GetColumnName< T,TResult>(表达式来; Func键< T,TResult> ;>物业) { VAR成员= GetMemberExpression(property.Body); 如果(成员== NULL)抛出新的ArgumentException(不能还原为一个成员访问,财产); 返回member.Member.Name; } MemberExpression GetMemberExpression(表达式体) {变种候选人=新的问答LT;表达>(); candidates.Enqueue(体); ,而(candidates.Count大于0) { VAR EXPR = candidates.Dequeue(); 如果(表达式为MemberExpression) {回报率((MemberExpression)表达式); } ,否则如果(表达式为UnaryExpression) { candidates.Enqueue(((UnaryExpression)表达式).Operand); } ,否则如果(表达式是BinaryExpression) { VAR二进制= EXPR为BinaryExpression; candidates.Enqueue(binary.Left); candidates.Enqueue(binary.Right); } ,否则如果(表达式为MethodCallExpression) { VAR方法= EXPR为MethodCallExpression; 的foreach(在method.Arguments VAR参数) { candidates.Enqueue(参数); } } ,否则如果(表达式为LambdaExpression) { candidates.Enqueue(((LambdaExpression)表达式)。体); } } 返回NULL; }

这产生输出,如:

GetColumnName((X)=> XX):X GetColumnName((X)=> XX + 2):X GetColumnName((X)=→2 + XX):X GetColumnName((X)=> -XX):X GetColumnName((X)=>数学。 SQRT(XY)):Y GetColumnName((X)=>的Math.sqrt(Math.Abs​​(XY))):Y

Hello,

I am using LINQ and EF with C# 4.0. I have dragged the basic ELMAH table into EF (built and saved many many times). All is working as one would expect.

But have tried to be too ambitious and need a little help - I am trying to get the Column name from an expression that is passed in as a variable.

What I want is this:

Pass in : 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 // i.e. {"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. }

Thank you for your help! Dan.

解决方案

If you need to also decompose simple (or nearly simple) expressions, you'll need some extra legwork to handle the different situations. Here is some starter code that handles 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; }

Which produces output like:

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

更多推荐

LINQ成员表达越来越列名

本文发布于:2023-10-31 06:32:39,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1545299.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:成员   LINQ

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!