Exception “Specified method is not supported.” being thrown from NHibernate IQueryable expression when using .Any extension

StackOverflow https://stackoverflow.com/questions/10938743

Question

Utilizing NHibernate I am attempting to use a lambda expression to retrieve objects based on the status and values between a parent child relationship. AbstractWorkflowRequestInformation has a collection of WorkflowRequestInformationAction. Each of the two classes have their own Status properties. To illustrate here are the abbreviated classes as they relate to this query:

public class AbstractWorkflowRequestInformation
{
    public virtual RequestStatus RequestStatus { get; set; }

    public virtual IEnumerable<WorkflowRequestInformationAction>
        WorkflowRequestInformationActionList { get; set; }
}

public class WorkflowRequestInformationAction
{
    public virtual ActionStatus Status { get; set; }

    public virtual string RoleIdentifier { get; set; }

    public virtual string RoleName { get; set; }
}

Given this relationship I want to retrieve AbstractWorkflowRequestInformation objects based on a List<KeyValuePair<string, string>> called roles. I realize that the exception is being caused by a lack of parsing of the Any(...) extension method, but I am unsure of alternative queries. Thus far all permutations on the below query have caused the same or similar exceptions:

public IEnumerable<IRequestInformation> GetRequestsPendingActionBy(
        List<KeyValuePair<string, string>> roles)
{
    var results = GetSession().Query<AbstractWorkflowRequestInformation>()
        .Where(r => r.RequestStatus == RequestStatus.Pending
                    && r.WorkflowRequestInformationActionList
                        .Any(a => ActionStatus.Pending == a.Status
                                  && roles.Any(kp => kp.Key == a.RoleName
                                               && kp.Value == a.RoleIdentifier)))
    .ToList();

    return results;
}

The ultimate goal is to retrieve only those AbstractWorkflowRequestInformation objects which are pending and have a pending WorkflowRequestInformationAction matching a KeyValuePair in the roles enumerable.

I am not wedded to using a lambda expression as this expression has already grown unwieldy, if there's a more elegant ICriteria expression I am all ears. What are my options to restrict my results based upon the values in my roles List<KeyValuePair<string, string>> but prevent the "Specified method is not supported" exception?

Was it helpful?

Solution

I think this would get same results...

WorkflowRequestInformationAction actionAlias = null;

var q = GetSession().QueryOver<AbstractWorkflowRequestInformation>()
    .Inner.JoinAlias(x => x.WorkflowRequestInformationActionList,
                          () => actionAlias)
    .Where(x => x.RequestStatus == RequestStatus.Pending)
    .And(() => actionAlias.Status == ActionStatus.Pending);

var d = Restrictions.Disjunction();

foreach(var kvp in roles) 
{
    d.Add(Restrictions.Where(() => actionAlias.RoleName == kvp.Key
                                  && actionAlias.RoleIdentitifier == kvp.Value));
}

q.And(d).TransformUsing(Transformers.DistinctRootEntity);

var results = q.List();

You could probably take a similar approach with NH Linq. I'm more comfortable with QueryOver/Criteria though.

OTHER TIPS

The LINQ provider in NHibernate is not fully supported, you are trying to execute an extension method on a part of the expression tree that is not parsed from the provider.

This post might help you solve the problem. Be sure to checkout the related posts.

Also see the post from Fabio Maulo on NHibernate LINQ provider extension.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top