如何获取一个方法来返回一个表达式来解决“在epression中无法识别的方法调用”错误?

时间:2010-07-30 15:16:57

标签: c# nhibernate lambda

我有以下声明:抛出一个我不理解的错误:

return (int) _session.CreateCriteria<T>()
    .Add(LambdaSubquery.Property<Fund>(x => x.Id)
        .In(GetAvailableIdsPerDataUniverse(x => x.GetDataUniverseId())))
    .AddNameSearchCriteria<T>(searchExpression)
    .SetProjection(LambdaProjection.Count<T>(e => e.Id))
    .UniqueResult();

这是错误:

  

在epression x.GetDataUniverseId()

中无法识别的方法调用

背景:

我有一些不同的类型需要执行搜索。这些类型中的每一种都实现ISearchable,这要求他们拥有Name&amp; Id属性以及GetDataUniverseId()方法,它将返回表示LambdaProjection所需的dataUniverseId的表达式。

方法GetAvailableIdsPerDataUniverse(x => x.GetDataUniverseId())具有以下签名:

protected DetachedCriteria 
GetAvailableIdsPerDataUniverse(System.Linq.Expressions.Expression<Func<Fund, object>> dataUniverseId)

x => x.GetDataUniverseId()在我的Fund课程中定义为

public virtual System.Linq.Expressions.Expression<Func<Fund, object>> GetDataUniverseId()
{
    return f => f.Id;
}

,例如Company类中的以下内容:

public virtual Expression<Func<Fund, object>> GetDataUniverseId()
{
    return f => f.Company.Id;
}

如果不是尝试将x => x.GetDataUniverseId()作为参数传递,而是“硬编码”f => f.Idf => f.Company.Id,则此方法有效。我喜欢它,如果正在处理的类型能够提供它所需的表达式,而不是我必须将该表达式传递给使用GetAvailableIdsPerDataUniverse()的每个方法。我认为它不是访问推断类型的属性,而是执行一个返回表达式的方法。

问题:

我有什么办法可以解决这个错误吗?

注意:

一切都很好,所以当我运行它时,我发现它犯了一个错误,我有点惊讶。主要是因为当我将表达式作为参数传递给我“硬编码”时,它工作正常。

另外,我也试过以下内容无济于事,我指定了我想要GetAvailableIdsPerDataUniverse作用的类型:

.In(GetAvailableIdsPerDataUniverse<Fund>(x => x.GetDataUniverseId())))

2 个答案:

答案 0 :(得分:1)

我被告知这里的问题是我想要多态静态方法的行为,但我不能这样,因为GetDataUniverseId不是一个实例方法,我需要一个实例才能以多态方式使用它

该解决方案尽管效率低,因为它使用了大量反射,但使用new T()

这样

    .Add(LambdaSubquery.Property<Fund>(x => x.Id)
        .In(GetAvailableIdsPerDataUniverse(x => x.GetDataUniverseId())))

变为

    .Add(LambdaSubquery.Property<Fund>(x => x.Id)
        .In(GetAvailableIdsPerDataUniverse((new T()).GetDataUniverseId())))

唯一的另一个问题是内部存在的方法:

    public IEnumerable<T> GetEntitiesByName<T>(int pageSize, string searchExpression)
        where T : class, ISearchableEntity

现在必须具有new()约束,如下所示:

    public IEnumerable<T> GetEntitiesByName<T>(int pageSize, string searchExpression) 
        where T : class, ISearchableEntity, new()

我希望有人能从这里找到更多用途,而不是@Sunny提供的'答案'

答案 1 :(得分:-1)

尝试:

return (int) _session.CreateCriteria<T>()
    .Add(LambdaSubquery.Property<Fund>(x => x.Id)
        .In(GetAvailableIdsPerDataUniverse(y => y.GetDataUniverseId())))
    .AddNameSearchCriteria<T>(searchExpression)
    .SetProjection(LambdaProjection.Count<T>(e => e.Id))
    .UniqueResult();