1

I have the following statement that's throwing an error I don't understand:

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

This is the error:

Unrecognised method call in epression x.GetDataUniverseId()

Background:

I have some different types that I need to perform searches for. Each of these types implement ISearchable which requires that they have Name & Id properties as well as the GetDataUniverseId() method, which will return an expression representing the dataUniverseId needed for the LambdaProjection.

The method GetAvailableIdsPerDataUniverse(x => x.GetDataUniverseId()) has the following signature:

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

and x => x.GetDataUniverseId() is defined in my Fund class as

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

and for example as the following in the Company class:

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

This works if instead of trying to pass x => x.GetDataUniverseId() as the parameter, I 'hard-code' f => f.Id or f => f.Company.Id. I'd like it if the type being worked on was able to supply the expression it needed rather than me having to pass that expression into every method that uses GetAvailableIdsPerDataUniverse(). I thought that instead of accessing a property on the inferred type, it could execute a method that would return the expression.

Question:

Is there anything I can do to resolve this error?

Note:

Everything builds fine, so I was a little surprised to see that it threw an error when I ran it. Mostly because when I passed in the expression as a parameter that I 'hard-coded' it worked fine.

Also, I've also tried the following to no avail, where I specify the type I want GetAvailableIdsPerDataUniverse to act on:

.In(GetAvailableIdsPerDataUniverse<Fund>(x => x.GetDataUniverseId())))
Cœur
  • 37,241
  • 25
  • 195
  • 267
DaveDev
  • 41,155
  • 72
  • 223
  • 385
  • Hi @DaveDev, I know this question is old, but would you be able to reproduce the error nowadays in order to double check the spelling of _epression_? Because two years after you, Ehsan reported a similar error in nhibernate with a spelling of _expression_ (https://stackoverflow.com/questions/9377774/queryover-error-unrecognised-method-call-in-expression-value), and if indeed the spelling was improved between 2010 and 2012, it may be best to update the question to match the actual error spelling. – Cœur Aug 21 '17 at 05:46

2 Answers2

1

I've been informed that the problem here is that I want the behaviour of polymorphic static methods, but I can't have that because GetDataUniverseId is not an instance method, and I need an instance to be able to use it polymorphically.

The solution, although inefficient because it uses lots of reflection is to use new T()

such that

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

becomes

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

The only other issue with this is that the method this exists inside:

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

must now have the new() constraint, as follows:

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

I hope somebody finds more use from this than the 'answer' provided by @Sunny

DaveDev
  • 41,155
  • 72
  • 223
  • 385
  • With all due respect DaveDev, I was under the impression that you we getting the error because 'x' was already defined in the previous lamba & so my 'answer'... – Sunny Aug 03 '10 at 20:42
  • If that's the case, fair enough. But I'm sure you can understand my frustration. If that was your genuine intent you should update your answer with an explanation. We can then work on squaring the record. – DaveDev Aug 03 '10 at 20:54
-1

Try:

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();
Sunny
  • 6,286
  • 2
  • 25
  • 27