2

私はこれを変換しようとしています:

ISession.Query<Question>()
    .Where(x => x.QuestionId == q.QuestionId)
    .FetchMany(x => x.Answers)
    .ToFuture();

リフレクションタイプへ:

IQueryable<Question> query = ISession.Query<Question>().Where(string.Format("{0} = @0", "QuestionId"), q.QuestionId);
Type emType = typeof(NHibernate.Linq.EagerFetchingExtensionMethods);
MethodInfo mi = emType.GetMethod("FetchMany");

ParameterExpression paramEx = Expression.Parameter(typeof(Question), "x");
MemberExpression me = Expression.Property(paramEx, "Answers");         
LambdaExpression lambdaEx = Expression.Lambda (me, paramEx);            

// runtime error here
mi.MakeGenericMethod(typeof(Question), typeof(Answer)).Invoke(emType, new object[] { query, lambdaEx }); 

実行時エラー:

System.ArgumentException: Object of type 
'System.Linq.Expressions.Expression`1
[System.Func`2[TestXXX.TheModels.Question,
System.Collections.Generic.IList`1[TestXXX.TheModels.Answer]]]' 

cannot be converted to type

'System.Linq.Expressions.Expression`1
[System.Func`2[TestXXX.TheModels.Question,
System.Collections.Generic.IEnumerable`1[TestXXX.TheModels.Answer]]]'.

POCO サンプル:

問題の回答は IList です。IList を IEnumerable に変更するようアドバイスしないでください ;-)

public class Question
{
    public virtual int QuestionId { get; set; }
    public virtual string QuestionText { get; set; }

    public virtual IList<Answer> Answers { get; set; }
}

FetchMany のメソッド シグネチャは次のとおりです。

namespace NHibernate.Linq
{
    public static class EagerFetchingExtensionMethods
    {
        public static INhFetchRequest<TOriginating, TRelated> Fetch<TOriginating, TRelated>(this IQueryable<TOriginating> query, Expression<Func<TOriginating, TRelated>> relatedObjectSelector);
        public static INhFetchRequest<TOriginating, TRelated> FetchMany<TOriginating, TRelated>(this IQueryable<TOriginating> query, Expression<Func<TOriginating, IEnumerable<TRelated>>> relatedObjectSelector);
        public static INhFetchRequest<TQueried, TRelated> ThenFetch<TQueried, TFetch, TRelated>(this INhFetchRequest<TQueried, TFetch> query, Expression<Func<TFetch, TRelated>> relatedObjectSelector);
        public static INhFetchRequest<TQueried, TRelated> ThenFetchMany<TQueried, TFetch, TRelated>(this INhFetchRequest<TQueried, TFetch> query, Expression<Func<TFetch, IEnumerable<TRelated>>> relatedObjectSelector);
    }
}

リフレクション中に IList を NHibernate の FetchMany の IEnumerable に渡すことができるようにするにはどうすればよいですか?

注: リフレクションを使用していない場合は、IList を IEnumerable に渡すことができます

4

1 に答える 1

2

これを変える

MemberExpression me = Expression.Property(paramEx, "Answers");         

これに:

Expression me = Expression.Convert(Expression.Property(paramEx, "Answers"), typeof(IEnumerable<Answer>));

受け取っているエラーの理由は、ラムダのデリゲート型が一致しないことです。IList<T>人為的に をとして扱うことで、型の互換性を持たせる必要がありIEnumerable<T>ます。

動的言語の支持者が言うように、これは一種のハックです ;-) とにかく、確実に動作します。

于 2012-06-19T16:11:19.077 に答える