【发布时间】:2014-07-28 19:58:45
【问题描述】:
我有以下表达式:
.Call System.Linq.Queryable.Select(
.Constant<System.Linq.EnumerableQuery`1[System.Linq.Dynamic.Tests.Helpers.User]>(System.Linq.Dynamic.Tests.Helpers.User[]),
'(.Lambda #Lambda1<System.Func`2[System.Linq.Dynamic.Tests.Helpers.User,System.Linq.Dynamic.DynamicObjectClass]>))
.Lambda #Lambda1<System.Func`2[System.Linq.Dynamic.Tests.Helpers.User,System.Linq.Dynamic.DynamicObjectClass]>(System.Linq.Dynamic.Tests.Helpers.User $var1)
{
.New System.Linq.Dynamic.DynamicObjectClass(
.New System.Collections.Generic.KeyValuePair`2[System.String, System.Object](
"UserName",
(System.Object)$var1.UserName),
.New System.Collections.Generic.KeyValuePair`2[System.String, System.Object](
"MyFirstName",
(System.Object)($var1.Profile).FirstName))
}
并想将其重写为以下内容:
.Call System.Linq.Queryable.Select(
.Constant<System.Linq.EnumerableQuery`1[System.Linq.Dynamic.Tests.Helpers.User]>(System.Linq.Dynamic.Tests.Helpers.User[]),
'(.Lambda #Lambda1<System.Func`2[System.Linq.Dynamic.Tests.Helpers.User,DynamicClass1]>))
.Lambda #Lambda1<System.Func`2[System.Linq.Dynamic.Tests.Helpers.User,DynamicClass1]>(System.Linq.Dynamic.Tests.Helpers.User $var1)
{
.New DynamicClass1()
{
UserName = $var1.UserName,
MyFirstName = ($var1.Profile).FirstName
}
}
我尝试使用 Expression Visitor 和以下代码:
protected override Expression VisitNew(NewExpression node)
{
if (node.Type == typeof(DynamicObjectClass))
{
var properties = new List<DynamicProperty>(node.Arguments.Count);
var expressions = new List<Expression>(node.Arguments.Count);
foreach (NewExpression newEx in node.Arguments)
{
var name = ((ConstantExpression)newEx.Arguments.First()).Value as string;
var parameter = ((UnaryExpression)newEx.Arguments.Skip(1).First()).Operand;
properties.Add(new DynamicProperty(name, parameter.Type));
expressions.Add(parameter);
}
Type type = DynamicExpression.CreateClass(properties);
MemberBinding[] bindings = new MemberBinding[properties.Count];
for (int i = 0; i < bindings.Length; i++)
bindings[i] = Expression.Bind(type.GetProperty(properties[i].Name), expressions[i]);
return Expression.MemberInit(Expression.New(type), bindings);
}
return base.VisitNew(node);
}
但我得到了这个例外:
发生“System.ArgumentException”类型的第一次机会异常 在 System.Core.dll 中
附加信息:“DynamicClass1”类型的表达式不能 用于返回类型'System.Linq.Dynamic.DynamicObjectClass'
我想我需要覆盖 VisitLambda,但我没有确切的想法!谁能帮帮我?
【问题讨论】:
-
英文翻译中的附加信息?谢谢。
-
“DynamicClass1”类型的表达式不能用于返回类型“System.Linq.Dynamic.DynamicObjectClass”
-
也许我可以多做一点说明:我已将 Dynamic Linq 项目转换为 WinRT!但在 WinRT 中,我无法通过反射发射生成新类型,因此我实现了一个“DynamicObject”,用于通常使用的 AnonymousTypes!现在,当我通过 WCF 发送这个表达式时(我仍然必须实现),然后我需要将表达式转换回来,以便它再次使用匿名类型,所以我的数据层可以将它转换为 SQL!
标签: c# linq expression expressionvisitor