2016-05-19 12 views
1

をビルドします。今まで、私は」、そうLINQの式 - >私のような<code>Expression<Func<TEntity, TKey>></code>構築しようとしている(...)シングル(...)LINQのツリー表現

e.Collection.Where(c => c.Key.Equals("key")).Single() 

を。そのようなものを作ることができました。しかし、私はWhere().Single()チェーン構築する方法を見つけ出すことは非常ないよ:それは私にスロー

Type entityType = typeof(TElementType); 
PropertyInfo collectionPropertyInfo = entityType.GetProperty("Metainfos"); // TODO: Pick the property up instead of using a literal string 
if (collectionPropertyInfo == null) 
    throw new MissingFieldException(string.Format("{0} collection doesn't appear in {1}", "MetaInfos", entityType)); 

Type collGenericType = collectionPropertyInfo.PropertyType.GetGenericArguments().FirstOrDefault(); 
if (!collGenericType.IsAssignableFrom(typeof(Domain.MetaInfoValue))) 
    throw new TypeLoadException(string.Format("Collection generic type doesn't inherit from {1}", collGenericType)); 

ParameterExpression entityParameter = Expression.Parameter(entityType, "t"); 
ParameterExpression metaInfoParameterExpression = Expression.Parameter(collGenericType, "m"); 

MemberExpression collectionMemberExpression = Expression.Property(entityParameter, collectionPropertyInfo); 
MethodInfo whereMethod = typeof(Enumerable).GetMethods().Where(m => m.Name.Equals("Where") && m.GetParameters().Length == 2).First().MakeGenericMethod(collGenericType); 
MethodInfo singleMethod = typeof(Enumerable).GetMethods().Where(m => m.Name.Equals("Single") && m.GetParameters().Length == 1).First().MakeGenericMethod(collGenericType); 

LambdaExpression innerCondition = Expression.Lambda(
    Expression.GetDelegateType(collGenericType, typeof(bool)), 
    Expression.Equal(
     Expression.Property(metaInfoParameterExpression, "Key"), 
     Expression.Constant(field) 
    ), 
    metaInfoParameterExpression 
); 

return Expression.Lambda<Func<TElementType, TKeyType>>(
    Expression.Call(
     singleMethod, 
     Expression.Lambda<Func<TElementType, bool>>(
      Expression.Call(whereMethod, collectionMemberExpression, innerCondition), 
      entityParameter 
     ) 
    ) 
);} 

ArgumentException

System.Boolean`

タイプ System.Collections.Generic.IEnumerable1[Backend.Domain.MetaInfoValue]</code> for the returned valueの表現を使用することを許可されていません

どういうところが間違っていますか?

+2

あなたはコンプリート、[最小を提供することができ、かつ検証可能な例](http://stackoverflow.com/help/mcve)? –

答えて

0

SingleExpression.Callのようです。あなたは(1)sourceと(2)argumentsを提供する必要があります。今、あなたは両方を同じ議論(Expression.Lambda<Func<TElementType, bool>>(Expression.Call(whereMethod, collectionMemberExpression, innerCondition), entityParameter);)として提供しようとしているようです。

Singleの表現は通常どのようなものか考えてみてください:myEnumerable.Single(o => o.Key == iKey);SourcemyEnumerable)が選択式(o => o.Key == iKey)とどのように違うのかを確認してください。

あなたはEnumerable入力と出力、および1つのセレクタ(Expression.Lambda<Func<TElementType, bool>>)を使用してSingleコール(1 sourceの引数として2つの式を作成した場合、それは問題を解決する必要があります。

関連する問題