LLBLGen TypedConstantExpression无法转换为SetExpression

时间:2013-05-07 13:40:20

标签: linq llblgenpro

我们遇到了在包含LINQ表达式中使用超过2100个元素的问题,因此我重写了查询以将先前在包含比较中使用的值插入到EnquiryID类型的IEnumerable结构中,从而暴露出一个简单的int值(ID)并加入了这个:

IEnumerable<EnquiryID> enqIdList = ListToEnquiryIdList(enquiryIDs).ToList();

var extras = (from q in lmd.Quote
join qe in lmd.QuoteExtra on q.Id equals qe.QuoteId
join ei in enqIdList on q.EnquiryId  equals ei.Id 
orderby qe.Created
select new
{
  EnquiryID = q.EnquiryId, qe.Created
}).ToArray();

这会产生此异常:

“无法将类型为'System.Linq.Expressions.TypedConstantExpression'的对象转换为'SD.LLBLGen.Pro.LinqSupportClasses.ExpressionClasses.SetExpression'。”,这显然是LLBLGEN特定的

有人有什么想法吗?

1 个答案:

答案 0 :(得分:1)

您可以访问“价值”&#39; TypedConstantExpression的属性如此:
 (expression.Body as MethodCallExpression).Object.GetType()。GetProperty(&#34; Value&#34;)。GetMethod.Invoke((expression.Body as MethodCallExpression).Object,null)

表达式由LambdaExpression ()=>(null).GetType()

提供

一个完整的例子

static readonly Type TypedConstantExpressionType = Type.GetType("System.Linq.Expressions.TypedConstantExpression, System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");

        static readonly PropertyInfo TypedConstantExpressionValueProperty;

        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized | System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        static SymbolExtensions()
        {
            TypedConstantExpressionValueProperty = IntrospectionExtensions.GetTypeInfo(TypedConstantExpressionType).GetProperty("Value");
        }

        /// <summary>
        /// Given a lambda expression that expressed a new object, returns the <see cref="System.Reflection.TypeInfo"/> of what type was expected to be allocated
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        public static TypeInfo GetTypeInfo(Expression<Action> expression) //Expression<Action> allows the syntax () => where Expression would require a Delgate.
        {
            Expression body = expression.Body;

            if (body is NewExpression)
            {
                NewExpression newExpression = expression.Body as NewExpression;

                return IntrospectionExtensions.GetTypeInfo((expression.Body as NewExpression).Constructor.DeclaringType);
            }
            else if (body is MemberExpression)
            {
                MemberExpression memberExpression = body as MemberExpression;

                return IntrospectionExtensions.GetTypeInfo(memberExpression.Member.DeclaringType);
            }
            else if (body is MethodCallExpression)
            {
                MethodCallExpression methodCallExpression = expression.Body as MethodCallExpression;

                if (methodCallExpression.Object is MemberExpression)
                {
                    return IntrospectionExtensions.GetTypeInfo((methodCallExpression.Object as MemberExpression).Member.DeclaringType);
                }

                //Actually a RuntimeType from a TypedConstantExpression...
                return IntrospectionExtensions.GetTypeInfo((Type)TypedConstantExpressionValueProperty.GetMethod.Invoke(methodCallExpression.Object, null));
            }

            throw new System.NotSupportedException("Please create an issue for your use case.");
        }

使用以下类和代码进行测试:

public class MyTestClass
        {
            string m_Test;

            public string Test
            {
                get { return m_Test; }
                set { m_Test = value; }
            }
        }

        public class MyTestClass<T> : MyTestClass
        {
            T Backing;

            public T Property
            {
                [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
                get { return Backing; }
                [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
                set { Backing = value; }
            }

            public T AnotherProperty
            {
                get;
                set;
            }
        }



System.Reflection.TypeInfo typeInfo = Media.Common.Extensions.ExpressionExtensions.SymbolExtensions.GetTypeInfo(() => new MyTestClass<int>());

            if (typeInfo.GetGenericArguments()[0] != typeof(int)) throw new System.Exception("Not correct type");

            System.Console.WriteLine("TypeInfo.Name" + typeInfo.Name);

            System.Console.WriteLine("TypeInfo.MetadataToken" + typeInfo.MetadataToken);

            if (typeInfo.GetGenericArguments()[0] != typeof(int)) throw new System.Exception("Not correct type");

            typeInfo = Media.Common.Extensions.ExpressionExtensions.SymbolExtensions.GetTypeInfo(() => (typeof(MyTestClass<int>)).GetType());

            if (typeInfo.GetGenericArguments()[0] != typeof(int)) throw new System.Exception("Not correct type");

            System.Type unboundedType = typeof(MyTestClass<>);

            typeInfo = Media.Common.Extensions.ExpressionExtensions.SymbolExtensions.GetTypeInfo(() => (unboundedType).GetType());

            System.Console.WriteLine("TypeInfo.Name" + typeInfo.Name);

            System.Console.WriteLine("TypeInfo.MetadataToken" + typeInfo.MetadataToken);