nHibernate 方法使用 Criteria 选择其子集合中的字符串包含特定搜索项的父项

发布于 2024-11-09 18:21:13 字数 2570 浏览 4 评论 0原文

我需要对公司地址进行搜索 - 如果一家公司在其地址之一中有某个字符串,那么它必须出现在搜索结果中(类似于正则表达式 '%string%' )。

公司的 nHibernate 映射文件如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="TaskMappings"
                   namespace="TaskMappings">
    <class name="Company">
        <id name="Id">
            <generator class="sequence">
                <param name="sequence">company_id_seq</param>
            </generator>
        </id>
        <property name="Name" />
        <property name="Fax" />
        <property name="PostalCode" />

        <bag name="Users" cascade="all-delete-orphan" inverse="true">
            <key column="UserCompany" />
            <one-to-many class="User" />
        </bag>

        <bag name="Phone" cascade="all-delete-orphan" lazy="false">
            <key column="PhoneCompany" />
            <element column="Phone" />
        </bag>

        <bag name="Email" cascade="all-delete-orphan" lazy="false">
            <key column="EmailCompany" />
            <element column="Email" />
        </bag>

        <bag name="Addresses" table="address" cascade="all-delete-orphan" lazy="false">
            <key column="AddressCompany" />
            <element column="Address" type="String"/>
        </bag>
    </class>
</hibernate-mapping>

公司实体类如下:

public class Company : Entity<int>
{
    public virtual string Name { get; set; }
    public virtual string Fax { get; set; }
    public virtual string PostalCode { get; set; }

    private IList<string> _phone = new List<string>();
    public virtual IList<string> Phone
    {
        get { return _phone; }
        set { _phone = value; }
    }

    private IList<string> _email = new List<string>();
    public virtual IList<string> Email
    {
        get { return _email; }
        set { _email = value; }
    }

    private IList<string> _addresses = new List<string>();
    public virtual IList<string> Addresses
    {
        get { return _addresses; }
        set { _addresses = value; }
    }

    private IList<User> users = new List<User>();
    public virtual IList<User> Users
    {
        get { return users; }
        set { users = value; }
    }
}

我的问题是:我如何最好使用条件进行搜索?我需要结果作为 IList。 感谢您的回答! :)

I need to do a search on company address - if a company has a certain string in one of it's addreses it must appear in the search results ( something like regex '%string%' ).

nHibernate mapping file for the Company looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="TaskMappings"
                   namespace="TaskMappings">
    <class name="Company">
        <id name="Id">
            <generator class="sequence">
                <param name="sequence">company_id_seq</param>
            </generator>
        </id>
        <property name="Name" />
        <property name="Fax" />
        <property name="PostalCode" />

        <bag name="Users" cascade="all-delete-orphan" inverse="true">
            <key column="UserCompany" />
            <one-to-many class="User" />
        </bag>

        <bag name="Phone" cascade="all-delete-orphan" lazy="false">
            <key column="PhoneCompany" />
            <element column="Phone" />
        </bag>

        <bag name="Email" cascade="all-delete-orphan" lazy="false">
            <key column="EmailCompany" />
            <element column="Email" />
        </bag>

        <bag name="Addresses" table="address" cascade="all-delete-orphan" lazy="false">
            <key column="AddressCompany" />
            <element column="Address" type="String"/>
        </bag>
    </class>
</hibernate-mapping>

and the Company entity class like this:

public class Company : Entity<int>
{
    public virtual string Name { get; set; }
    public virtual string Fax { get; set; }
    public virtual string PostalCode { get; set; }

    private IList<string> _phone = new List<string>();
    public virtual IList<string> Phone
    {
        get { return _phone; }
        set { _phone = value; }
    }

    private IList<string> _email = new List<string>();
    public virtual IList<string> Email
    {
        get { return _email; }
        set { _email = value; }
    }

    private IList<string> _addresses = new List<string>();
    public virtual IList<string> Addresses
    {
        get { return _addresses; }
        set { _addresses = value; }
    }

    private IList<User> users = new List<User>();
    public virtual IList<User> Users
    {
        get { return users; }
        set { users = value; }
    }
}

My question is: how can i do the search using criteria preferably? I need the result as an IList.
Thanks for your answers! :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

℡寂寞咖啡 2024-11-16 18:21:13

您可以尝试:

确保您的地址实体上有一个公司并在其映射中引用它,然后将地址的公司实体更改为:

private IList<Address> _addresses = new List<Address>();
public virtual IList<Address> Addresses
{
    get { return _addresses; }
    set { _addresses = value; }
}

然后尝试此条件:

var criteria = DetachedCriteria.For<Company>()
   .CreateCriteria("this.Addresses", "a")
   .SetFetchMode("a", FetchMode.Join)
   .Add(Restrictions.InsensitiveLike("a.Address", <string variable>, MatchMode.Anywhere))
   .SetResultTransformer(new DistinctRootEntityTransformer());

然后在您拥有的任何会话中执行该条件。我的问题是,为什么地址映射到 Company,而只是一个字符串列表?如果地址是映射到公司的实体,这将为您简化事情。

You could try:

ensure your Address entity has a Company on it and references it in its mapping then change your company entity for addresses to:

private IList<Address> _addresses = new List<Address>();
public virtual IList<Address> Addresses
{
    get { return _addresses; }
    set { _addresses = value; }
}

and then try this criteria:

var criteria = DetachedCriteria.For<Company>()
   .CreateCriteria("this.Addresses", "a")
   .SetFetchMode("a", FetchMode.Join)
   .Add(Restrictions.InsensitiveLike("a.Address", <string variable>, MatchMode.Anywhere))
   .SetResultTransformer(new DistinctRootEntityTransformer());

And then just execute that criteria in whatever session you have. My question is, why are addresses mapped onto Company, but are simply a list of strings? It would simplify things for you if Addresses were an entity mapped onto company.

等数载,海棠开 2024-11-16 18:21:13

看起来这不能使用 Criteria API 来完成(尽管我不是 100%)请参阅此处了解另一个类似的问题。但我已经设法使用 HQL 查询让它工作。

var query = session.CreateQuery("select c from Company c 
join c.Addresses a where a like '%string%'").List<Company>();

Looks like this cannot be done using the Criteria API (although I'm not 100%) see here for another similar question. But I have managed to get it to work using a HQL query.

var query = session.CreateQuery("select c from Company c 
join c.Addresses a where a like '%string%'").List<Company>();
同展鸳鸯锦 2024-11-16 18:21:13

像这样的东西:

HibernateDelegate<IList<IAssetLiabilityModel>> del = delegate(ISession session)
    {
        ICriteria criteria = session.CreateCriteria(typeof(ICompany));
        criteria.CreateCriteria("Company.Addresses", "Addresses");
        criteria.Add(Restrictions.Like("Addresses",<your_search_string>)); 
        criteria.SetResultTransformer(CriteriaSpecification.DistinctRootEntity);
        HibernateTemplate.PrepareCriteria(criteria);
        return criteria.List<ICompany>();
    };
    IList<ICompany> companies = HibernateTemplate.Execute(del);

Something like:

HibernateDelegate<IList<IAssetLiabilityModel>> del = delegate(ISession session)
    {
        ICriteria criteria = session.CreateCriteria(typeof(ICompany));
        criteria.CreateCriteria("Company.Addresses", "Addresses");
        criteria.Add(Restrictions.Like("Addresses",<your_search_string>)); 
        criteria.SetResultTransformer(CriteriaSpecification.DistinctRootEntity);
        HibernateTemplate.PrepareCriteria(criteria);
        return criteria.List<ICompany>();
    };
    IList<ICompany> companies = HibernateTemplate.Execute(del);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文