используйте nhibernate ResultTransformer - PullRequest
0 голосов
/ 02 января 2012

Я использую последнюю версию Nhibernate в своем проекте MVC

Я хочу сделать запрос к объекту с именами типа «Персона», но персона имеет много свойств.В одном из моих запросов я бы лучше не обладал большинством этих свойств.Вот Person:

public partial class Person
{
    virtual public User User { get; set; }
    virtual public string FirstName { get; set; }
    virtual public string LastName { get; set; }
    virtual public int Gender { get; set; }
    virtual public Contact Contact { get; set; }
    virtual public BirthCertificate PersonBirthCertificate { get; set; }
}

В запросе я просто хочу указать имя и фамилию человека.

Поэтому я решил использовать ResultTransformer и реализовать его следующим образом:

public class PersonResultTransformer : IResultTransformer
{
    private Type result;
    private PropertyInfo[] properties;

    #region IResultTransformer Members

    public IList TransformList(IList collection)
    {
        return collection;
    }
    public PersonResultTransformer (Type result, params string[] names)
    {
        this.result = result;
        List<PropertyInfo> props = new List<PropertyInfo>();
        foreach (string name in names)
        {
            props.Add(result.GetProperty(name));
        }
        properties = props.ToArray();
    }

    public object TransformTuple(object[] tuple, string[] aliases)
    {
        object instance = Activator.CreateInstance(result);
        for (int i = 0; i < tuple.Length; i++)
        {
            var t = properties[i].Name;

            var value = tuple[i].GetType().GetProperty(t).GetValue(tuple[i], null);
            instance.GetType().GetProperty(t).SetValue(instance, value, null);
        }
        return instance;
    }

    #endregion
}

и для получения желания я хочу с запросом linq:

var person = Repository<Person>.Find(p => p.LastName.Equals("Nadal")
   , new PersonResultTransformer (typeof(Person), "FirstName", "LastName"));

////////////////

public IQueryable<T> Find(Expression<Func<T, bool>> expression, IResultTransformer transformer)
{
    return Session.CreateCriteria<T>().SetResultTransformer(transformer).List<T>()
        .AsQueryable().Where(expression);

}

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

Кажется, что у него есть большая проблема: он получает имя и фамилию всех людей, а затем выбирает из них тех, которые имеют фамилию = "nadal", а производительность нехорошо вообще

Ответы [ 3 ]

3 голосов
/ 02 января 2012

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

using NHibernate.Linq;

public IQueryable<T> Find(Expression<Func<T, bool>> expression)
{
    return Session.Query<T>().Where(expression);
}

, затем вы можете

var personDTOs = Repository<Person>.Find(p => p.LastName.Equals("Nadal"))
    .Select(person => new { person.FirstName, person.LastName });

вы можете значительно сократить преобразователь результата, но вы не можете использовать его с Linq2NHibernate.

public class PersonResultTransformer : IResultTransformer
{
    private Type result;
    private List<PropertyInfo> properties = new List<PropertyInfo>();

    public IList TransformList(IList collection)
    {
        return collection;
    }
    public PersonResultTransformer (Type result, params string[] names)
    {
        this.result = result;
        foreach (string name in names)
        {
            properties.Add(result.GetProperty(name));
        }
    }

    public object TransformTuple(object[] tuple, string[] aliases)
    {
        object instance = Activator.CreateInstance(result);
        for (int i = 0; i < tuple.Length; i++)
        {
            properties[i].SetValue(instance, tuple[i], null);
        }
        return instance;
    }
}
0 голосов
/ 02 января 2012

Я могу ошибаться, но я думаю, что вы перестарались.

Вы могли бы легче использовать отложенную загрузку, чтобы не получать ненужные свойства.

0 голосов
/ 02 января 2012

Вы используете Session.CreateCriteria<T>(), но не добавляете к этому критерию .Таким образом, запрос выполняется без критериев, а затем преобразуется и фильтруется.

Вы должны найти способ добавить свои спецификации к методу Find таким образом, который может обрабатывать ICriteria в Nhibernate, или использовать Linqв Nhibernate (остерегайтесь некоторых проблем, хотя!).

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