Метод nHibernate, использующий Критерии для выбора родителей, для которых строки в их дочерней коллекции содержат определенный критерий поиска - PullRequest
1 голос
/ 25 мая 2011

Мне нужно выполнить поиск по адресу компании - если у компании есть определенная строка в одном из адресов, она должна появиться в результатах поиска (что-то вроде регулярного выражения '% 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 ]

1 голос
/ 25 мая 2011

Похоже, что это невозможно сделать с помощью Criteria API (хотя я не на 100%) см. Здесь другой похожий вопрос Но мне удалось заставить его работать, используя HQL-запрос.

var query = session.CreateQuery("select c from Company c 
join c.Addresses a where a like '%string%'").List<Company>();
1 голос
/ 25 мая 2011

Вы можете попробовать:

убедитесь, что в вашей организации-адресате есть компания, и она ссылается на нее в своем сопоставлении, а затем измените адрес вашей компании на адреса:

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, а представляют собой просто список строк? Было бы проще для вас, если бы Адреса были сущностью, сопоставленной с компанией.

0 голосов
/ 25 мая 2011

Что-то вроде:

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...