Как получить метод, возвращающий выражение для устранения ошибки «Нераспознанный вызов метода в выражении»? - PullRequest
1 голос
/ 30 июля 2010

У меня есть следующее утверждение, которое выдает ошибку, которую я не понимаю:

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();

Это ошибка:

Нераспознанный вызов метода в выражении x.GetDataUniverseId ()

Фон:

У меня есть несколько разных типов, которые мне нужны для поиска. Каждый из этих типов реализует ISearchable, который требует, чтобы они имели свойства Name & Id, а также метод GetDataUniverseId(), который будет возвращать выражение, представляющее dataUniverseId, необходимый для LambdaProjection.

Метод 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() в качестве параметра, я 'hard-code' f => f.Id или f => f.Company.Id. Мне бы хотелось, чтобы тип, над которым работали, мог предоставить нужное ему выражение, а не передавать это выражение в каждый метод, использующий GetAvailableIdsPerDataUniverse(). Я подумал, что вместо доступа к свойству выведенного типа, он может выполнить метод, который будет возвращать выражение.

Вопрос:

Что я могу сделать, чтобы устранить эту ошибку?

Примечание:

Все прекрасно работает, поэтому я был немного удивлен, увидев, что он выдал ошибку при запуске. Главным образом потому, что когда я передавал выражение как параметр, который я «жестко запрограммировал», оно работало нормально.

Кроме того, я также попробовал следующее безрезультатно, где я указываю тип, с которым я хочу GetAvailableIdsPerDataUniverse действовать:

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

Ответы [ 2 ]

1 голос
/ 30 июля 2010

Мне сообщили, что проблема в том, что мне нужно поведение полиморфных статических методов, но я не могу этого иметь, потому что 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

0 голосов
/ 30 июля 2010

Попробуйте:

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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...