views:

70

answers:

5

I have an entity Person:

public class Person
{
   public virtual int Id {get; set; }
   public virtual string FirstName { get; set; }
   public virtual string MiddleName { get; set; }
   public virtual string LastName { get; set; }
}

with the mappings:

public class PersonMap
{
   public PersonMap()
   {
       Table(TABLE_NAME); 
       Id( x => x.Id);
       Map(x => x.FirstName).Not.Nullable();
       Map(x => x.LastName).Not.Nullable();
       Map(x => x.MiddleName).Not.Nullable();
    }
}

There are some stuations where I would like Nhibernate to return a dictionary instead of the entity:

IDictionary<string,string> person = session.Get(id);//????
string firstName = person["FirstName"];

Is this possible to without adding a different mapping?

A: 

Look at this blog post:

http://sdesmedt.wordpress.com/2006/09/04/nhibernate-part-4-mapping-techniques-for-aggregation-one-to-many-mapping/

If you want a concrete example, check the samples of this nice tutorial. Look at the summaries that are not entities and have custom mapping logic:

http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx

Or do a google search on SetResultTransformer that is available just for that, transform results in another objects or collections. Including IDictionnary.

Pierre 303
Can you provide an example of using a results transformer to populate a dictionary? I don't think it's possible without writing a custom IResultTransformer.
Jamie Ide
Yes you have to write code. Writing clean code is sometimes require more efforts.
Pierre 303
A: 

No, but you can easily accomplish that by encapsulating the logic in a repository method.

public IDictionary<string, string> GetPersonDictionary(int id)
{
    var person = session.Get<Person>(id);
    var dict = new Dictionary<string, string>();
    dict.Add("FirstName", person.FirstName);
    /// etc.
    return dict;
}

You could also use reflection to populate the dictionary.

Jamie Ide
+1  A: 
session.CreateCriteria<Person>()
.SetResultTransformer(NHibernate.Transform.Transformers.AliasToEntityMap) 
.List<Hashtable>();

something like this?

Wayne
@wayne, that is very close to what I want to do. The problem with that is each hashtable has one key value pair in it where the person object is the value. I am trying to get a hashtable that has each property as a key value pair.
Maudite
A: 

You can do this by performing a client-side linq projection, see Diego's answer to this post.

DanP
@DanP, That is close to what I am trying to do; however, I do not think it is possible to use projections to create a KeyValuePair for a column name and its value.
Maudite
@Maudite: Alright..I see what you're getting at..let me post a new answer with an example result transformer impl.
DanP
+2  A: 

You will need to define your own ResultTransformer implementation to have this working the way you need it. Below is a reference implementation that you can tweak as needed. There is a complete lack of error-checking, etc; so use with caution ;)

using System;
using System.Collections;
using NHibernate;
using NHibernate.Properties;
using NHibernate.Transform;


[Serializable]
public class DictionaryResultTransformer : IResultTransformer
{

        public DictionaryResultTransformer()
        {

        }

        #region IResultTransformer Members

        public IList TransformList(IList collection)
        {
                return collection;
        }

        public object TransformTuple(object[] tuple, string[] aliases)
        {
          var result = new Dictionary<string,object>();
          for (int i = 0; i < aliases.Length; i++)
          {
            result[aliases[i]] = tuple[i];                         
          }
          return result;
        }

        #endregion
}
DanP