我在我的MVC项目中使用Nhibernate最后一个版本
我想对对象类型名称“Person”进行查询,但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”,并且表现并不好
答案 0 :(得分:3)
首先你必须委托一个理解表达式的查询
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 });
你可以大量缩短resulttransformer,但你不能在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;
}
}
答案 1 :(得分:0)
您使用Session.CreateCriteria<T>()
但不Find
。因此,查询在没有条件的情况下执行,然后进行转换和过滤。
你必须找到一种方法,以Nhibernate的ICriteria
可以处理的方式将你的规范添加到{{1}}方法,或者使用Linq to Nhibernate(但要注意一些问题!)。
答案 2 :(得分:0)
我可能错了 - 但我认为你过度了。
您可以更轻松地利用延迟加载来获取不需要的属性。