Возможно ли для nhibernate вернуть запрос как IDictionary вместо класса сущностей? - PullRequest
8 голосов
/ 03 сентября 2010

У меня есть юридическое лицо:

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

с отображениями:

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

В некоторых случаях я бы хотел, чтобы Nhibernate возвращал словарь вместо сущности:

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

Возможно ли это без добавления другого сопоставления?

Ответы [ 6 ]

12 голосов
/ 07 сентября 2010

Вам нужно будет определить собственную реализацию ResultTransformer, чтобы она работала так, как вам нужно. Ниже приведена справочная реализация, которую вы можете настроить по мере необходимости. Существует полное отсутствие проверки ошибок и т. Д .; так что используйте с осторожностью;)

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
}
2 голосов
/ 07 ноября 2011

Вам не нужно DictionaryResultTransformer, которое DanP отправил. AliasToEntityMapTransformer делает то же самое, хотя ни один не будет работать самостоятельно.Вы получите словарь сущностей.

Единственный способ, который я нашел, - это проецировать каждое свойство индивидуально.Однако вы не хотите делать это вручную, потому что оно сломается всякий раз, когда вы меняете свое отображение.Решение выглядит примерно так:

var criteria = DetachedCriteria.For<Person>();
criteria.Add(Restrictions.Eq("Id", id));
var projectionList = Projections.ProjectionList();
var metadata = session.SessionFactory.GetClassMetadata(typeof(Person));
foreach (var name in metadata.PropertyNames)
{
    projectionList.Add(Projections.Property(name), name);
}
criteria
    .SetProjection(projectionList)
    .SetResultTransformer(Transformers.AliasToEntityMap);
var result = criteria.GetExecutableCriteria(session)
    .UniqueResult<IDictionary>()

В приведенном выше примере я использую запрос для имитации Get.Конечно, вы можете немного изменить это и вернуть коллекцию;просто позвоните List<T> вместо UniqueResult<T>.

2 голосов
/ 06 сентября 2010
session.CreateCriteria<Person>()
.SetResultTransformer(NHibernate.Transform.Transformers.AliasToEntityMap) 
.List<Hashtable>();

как то так?

1 голос
/ 05 сентября 2010

Нет, но вы можете легко сделать это, заключив логику в метод репозитория.

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

Вы также можете использовать отражение для заполнения словаря.

0 голосов
/ 07 сентября 2010

Вы можете сделать это, выполнив проекцию linq на стороне клиента, см. Ответ Диего на это сообщение .

0 голосов
/ 03 сентября 2010

Посмотрите на эту запись в блоге:

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

Если вы хотите конкретный пример, посмотрите образцы этого замечательного урока.Посмотрите на сводки, которые не являются сущностями и имеют собственную логику сопоставления:

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

Или выполните поиск в Google по SetResultTransformer , который доступен только для этого, преобразуйтеприводит к другим объектам или коллекциям.В том числе IDictionnary.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...