1

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! :)

Răzvan Flavius Panda
  • 21,730
  • 17
  • 111
  • 169

3 Answers3

1

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>();
Community
  • 1
  • 1
Mark Perry
  • 1,705
  • 10
  • 12
1

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.

Fourth
  • 9,163
  • 1
  • 23
  • 28
  • How do i use the DetachedCriteria to get the List() returned? – Răzvan Flavius Panda May 25 '11 at 12:44
  • I figured out how to run it but it gives the error: "illegal syntax near collection: a Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: NHibernate.QueryException: illegal syntax near collection: a" – Răzvan Flavius Panda May 25 '11 at 12:53
  • modified it, you could try that one. i still dont see what addresses is mapped like an entity but is just a collection of strings - how does that wind up in your database? – Fourth May 25 '11 at 13:01
  • In the database the addresses are in a separate table named Address with 3 fields: Id, AddressCompany(foreign key) and Address(value). Ok. I'll give it a try. – Răzvan Flavius Panda May 25 '11 at 13:04
  • modified my answer to include the new details you gave about addresses :) – Fourth May 25 '11 at 13:17
  • Now it gives the error: "ERROR: 42601: syntax error at or near ":" Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: Npgsql.NpgsqlException: ERROR: 42601: syntax error at or near ":" " – Răzvan Flavius Panda May 25 '11 at 13:18
  • try my new answer details - it should work then once you fix up your entities and mappings – Fourth May 25 '11 at 13:20
  • I done remapping and added the Address entity but now i am getting another error. [Error](http://i.imgur.com/9PYQr.png) [Company mapping](http://i.imgur.com/anCec.png) [Address mapping](http://i.imgur.com/o85Qx.png) [Company entity](http://i.imgur.com/1BcQ5.png) [Address entity](http://i.imgur.com/ElyGp.png). Any ideea what is the problem? I am a beginner with NHibernate and C#. :) – Răzvan Flavius Panda May 25 '11 at 14:04
  • I finally managed to make it work. I had to use ".SetResultTransformer(Transformers.DistinctRootEntity);" as last line of code since i didn't knew how to add using for "new DistinctRootEntityTransformer()". Thanks a lot for your help! :D – Răzvan Flavius Panda May 25 '11 at 14:39
0

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);
Oleg
  • 798
  • 3
  • 7
  • in what assembly can i find HibernateDelegate, HibernateTemplate etc.? i am a beginner at nHibernate and this code looks rather complex :) – Răzvan Flavius Panda May 25 '11 at 11:19
  • @Freeman, Sorry, I'm currently using NHibernate so I gave an example for NHibernate, and these things are parts of NSpring.Hibernate. So I guess it won't fit you. But you can just remove those things. They only serve to make hibernate request act on a separate thread. While your problem afaiu is creating criteria itself – Oleg May 25 '11 at 12:06
  • @Freeman. Oh I'm blind today. You ARE using NHibernate :). You will find it on Spring.Data.NHibernate.Generic namespace. In Spring.Data.Nhibernate31 – Oleg May 25 '11 at 12:11
  • @Oleg. Where can i find Spring.Data.NHibernate.Generic? I only added 2 DLL's to the references: NHibernate and NHibernate.ByteCode.Castle. – Răzvan Flavius Panda May 25 '11 at 12:23
  • @Freeman, If you are not using Spring (why? imho it combines nice with NHibernate). Then just omit these things (as I said previously). You already have all the code for Criteria you need – Oleg May 25 '11 at 12:41
  • @Oleg, ok, i will give it a try. – Răzvan Flavius Panda May 25 '11 at 12:54
  • @Oleg. I got the error "could not resolve property: Company of: TaskMappings.Company Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: NHibernate.QueryException: could not resolve property: Company of: TaskMappings.Company" – Răzvan Flavius Panda May 25 '11 at 13:11
  • @Oleg. The code i run was: "return Session.CreateCriteria().CreateCriteria("Company.Addresses", "Addresses").Add(Restrictions.Like("Addresses", AddressSearchTerm)).SetResultTransformer(CriteriaSpecification.DistinctRootEntity).List();" – Răzvan Flavius Panda May 25 '11 at 13:12