nHibernate方法使用Criteria选择父类,其子集合中的字符串包含特定的searchterm

时间:2011-05-25 10:27:20

标签: c# nhibernate criteria

我需要搜索公司地址 - 如果公司在其中一个地址中有某个字符串,则必须出现在搜索结果中(例如regex'%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。 谢谢你的回答! :)

3 个答案:

答案 0 :(得分:1)

使用Criteria API(虽然我不是100%)see here for another similar question看起来无法做到这一点。但我已设法使用HQL查询使其工作。

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

答案 1 :(得分:1)

你可以尝试:

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

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

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

答案 2 :(得分:0)

类似的东西:

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