Search code examples
c#nhibernatedetachedcriterianhlambdaextensions

NHibernate Lambda Extensions can't use any alias query on DetachedCriteria


I'm trying to write a simple query that requires an alias as it's a Many-To-Many assocation however I can't get it to work with NH Lambda Extensions. It always gives me a compile error even though as far as I can tell it's exactly the same as the documentation and all the examples I've seen online.

Works

var query = DetachedCriteria.For<County>()            
    .CreateCriteria("Zips", "zipAlias", JoinType.LeftOuterJoin)
    //.CreateCriteria<County>(x => x.Zips, 
    //                              () => zipAlias, JoinType.LeftOuterJoin)
    .Add<Zip>(zip => zip.ZipCode == zipCode);

Doesn't work

var query = DetachedCriteria.For<County>()            
    //.CreateCriteria("Zips", "zipAlias", JoinType.LeftOuterJoin)
    .CreateCriteria<County>(x => x.Zips, 
                                    () => zipAlias, JoinType.LeftOuterJoin)
    .Add<Zip>(zip => zip.ZipCode == zipCode);

Results in a build Error 22 The name 'zipAlias' does not exist in the current context

Intellisense also highlights the CreateCriteria**<County>** saying it doesn't understand the method however it does correctly show me the parameter names when I'm inside the parens.


Solution

  • The documentation is full of handy examples.

    Your zipAlias needs to be a variable in the local scope.

    Zip zipAlias = null;
    string zipCode = "";
    
    var query = DetachedCriteria.For<County>()
        .CreateCriteria<County>(x => x.Zips, () => zipAlias, JoinType.LeftOuterJoin)
        .Add<Zip>(zip => zip.ZipCode == zipCode);
    

    As the documentation link downloads instead of rendering, I have copied some sections.

    Create Criteria Association With Alias
    Using original ICriteria API:

    ICriteria before = CreateSession()
        .CreateCriteria(typeof(Person))
            .CreateCriteria("Children", "childAlias")
                .Add(Restrictions.Eq("Nickname", "test"));
    

    Using NHibernate Lambda Extensions:

    Child childAlias = null;
    ICriteria after = CreateSession()
        .CreateCriteria(typeof(Person))
            .CreateCriteria((Person p) => p.Children, () => childAlias)
                .Add<Child>(c => c.Nickname == "test");
    

    Create Criteria Alias Association With Alias And Join Type
    Using original ICriteria API:

    ICriteria before = CreateSession()
        .CreateCriteria(typeof(Person), "personAlias")
            .CreateCriteria("personAlias.Children", "childAlias", JoinType.LeftOuterJoin)
                .Add(Restrictions.Eq("Nickname", "test"));
    

    Using NHibernate Lambda Extensions:

    Person personAlias = null;
    Child childAlias = null;
    ICriteria after = CreateSession()
        .CreateCriteria(typeof(Person), () => personAlias)
            .CreateCriteria(() => personAlias.Children, () => childAlias, JoinType.LeftOuterJoin)
                .Add<Child>(c => c.Nickname == "test");
    

    Create Criteria Association With Alias And Join Type
    Using original ICriteria API:

    DetachedCriteria before =
        DetachedCriteria.For<Person>()
            .CreateCriteria("Children", "childAlias", JoinType.LeftOuterJoin)
                .Add(Restrictions.Eq("Nickname", "test"));
    

    Using NHibernate Lambda Extensions:

    Child childAlias = null;
    DetachedCriteria after =
        DetachedCriteria.For<Person>()
            .CreateCriteria((Person p) => p.Children, () => childAlias, JoinType.LeftOuterJoin)
                .Add<Child>(c => c.Nickname == "test");