NHibernate How do I query against an IList property?

后端 未结 6 752
死守一世寂寞
死守一世寂寞 2020-11-29 10:37

I am trying to query against an IList property on one of my domain classes using NHibernate. Here is a simple example to demonstrate:

public cl         


        
相关标签:
6条回答
  • 2020-11-29 10:59

    As documented here:

    17.1.4.1. Alias and property references

    we can use:

    ...
    A collection key             {[aliasname].key}      ORGID as {coll.key}
    The id of an collection      {[aliasname].id}       EMPID as {coll.id}
    The element of an collection {[aliasname].element}  XID as {coll.element}
    ...
    

    there is a small bug in doc... instead of ".element" we have to use ".elements"

    var demos = this.session.CreateCriteria<Demo>()
            .CreateAlias("Tags", "t")
    
            // instead of this
            // .Add(Restrictions.Eq("t", "a"))
    
            // we can use the .elements keyword
            .Add(Restrictions.Eq("t.elements", "a"))
    
            .List<Demo>();
    
    0 讨论(0)
  • 2020-11-29 10:59

    You need to use SubCriterias not alias. This should work:

    var demos = this.session.CreateCriteria<Demo>()
                .CreateCriteria("Tags")
                .Add(Restrictions.Eq("Tag", "a"))
                .List<Demo>();
    
    0 讨论(0)
  • 2020-11-29 11:01

    Switching to a class over a string is one compromise. Using HQL instead of ICriteria is another. There is a third compromise however... use custom SQL. Try this out.

    var demos = Session.CreateCriteria<Demo>()
        .Add(Expression.Sql(
            "EXISTS (SELECT 1 FROM [Tags] custom_sql_t WHERE custom_sql_t.[DemoId] = {alias}.[Id] AND custom_sql_t.[Tag] = ?)",
            "a",
            NHibernateUtil.String))
        .List<Demo>();
    

    This results in the follwing SQL being generated by NHibernate 2.1.2.4000...

    exec sp_executesql N'SELECT this_.Id as Id2_0_, this_.Version as Version2_0_, this_.Name as Name2_0_ FROM Demo this_ WHERE EXISTS (SELECT 1 FROM [Tags] custom_sql_t WHERE custom_sql_t.[DemoId] = this_.[Id] AND custom_sql_t.[Tag] = @p0)',N'@p0 nvarchar(1)',@p0=N'a'
    

    See this post for another example...

    NHibernate - Querying from a collection of Value Types (non-Entity) to solve Select N+1

    0 讨论(0)
  • 2020-11-29 11:06

    This is possible by creating a separate criteria:

    ICriteria demoCriteria = session.CreateCriteria<Demo>();
    ...
    demoCriteria.Add(Restrictions...);
    ...
    ICriteria tagCriteria = demoCriteria.CreateCriteria("Tags");
    tagCriteria.Add(Restrictions.In("elements", new {"Tag1", "Tag2", ...}));
    
    return demoCriteria.List<Demo>();
    
    0 讨论(0)
  • 2020-11-29 11:11

    So because of limitations of the Criteria API, I decided to bend my domain classes to fit.

    I created an entity class for the Tag. I couldn't even create it as a value object. It had to have its own id.

    I feel dirty now. But being able to construct a dynamic query without resorting to string manipulation was more important to me than staying true to the domain.

    0 讨论(0)
  • 2020-11-29 11:18

    HQL:

    from Demo d where :val in elements(d.Tags)
    
    0 讨论(0)
提交回复
热议问题