NHibernate How do I query against an IList<string> property?

橙三吉。 提交于 2019-11-27 02:06: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.

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

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

HQL:

from Demo d where :val in elements(d.Tags)
Adam Boddington

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

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>();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!