c# - 如何在 lambda 表达式期间使 IList 兼容 IEnumerable?

标签 c# reflection lambda

我正在尝试转换它:

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

最佳答案

改变这个

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

对此:

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

您收到错误的原因是您的 lambda 的委托(delegate)类型不一致。我们需要通过人为处理IList<T>来使类型兼容。作为IEnumerable<T> .

正如任何动态语言的支持者都会说的那样,这是一种黑客行为;-)无论如何,它可靠地工作。

关于c# - 如何在 lambda 表达式期间使 IList 兼容 IEnumerable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11104913/

相关文章:

c# - System.Speech.Recognition 的问题 - SpeechRecognitionEngine 不接收语音

c# - 是否可以在多个项目之间共享 ResourceDictionary 文件?

c# - 为什么此 char 不显示 IDE 中的默认 char 方法?

c# - 无法通过反射将方法组转换为非委托(delegate)类型

.net - 从 getter/setter 的 MethodInfo 中查找托管 PropertyInfo

c# - 长期使用Entities时在C#中使用EntityFramework

c# - 任何人都知道一种快速获取枚举值自定义属性的方法吗?

c# - Lambda 表达式转换

mysql - 如何插入批量记录

lambda - lambda 表达式中逗号的 F# 语法