我正在尝试转换它:
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答案 0 :(得分:1)
更改此
MemberExpression me = Expression.Property(paramEx, "Answers");
到此:
Expression me = Expression.Convert(Expression.Property(paramEx, "Answers"), typeof(IEnumerable<Answer>));
您收到错误的原因是您的lambda的委托类型不同意。我们需要通过人为地将IList<T>
视为IEnumerable<T>
来使类型兼容。
这是一种黑客攻击,因为动态语言的任何支持者都会说;-)无论如何,它可靠地起作用。