NHibernate 在 Core 2.2 Framework 中的查询






3.67/5 (3投票s)
在本文中,我们描述了使用 NHibernate 查询方法的多种方式,我们涵盖了一些查询语法,但请参考 NHibernate 文档以查找更多功能,但哪个是适合初学者的呢?
引言
NHibernate O/RM 框架是 Entity Framework 的一个竞争者,它们是旧 .NET 框架中最受欢迎的框架之一。
NHibernate 架构应用了关注点分离,例如,它确保了工作单元与其配置(实体和映射)之间的分离。
对于一些开发人员来说,在 NHibernate 中处理映射类总是很复杂,因为你必须手动完成,但这在 Entity Framework 中更容易,即使它们都支持在实体创建中使用 POCO(普通旧 CLR 对象)。对于 ORM 来说,最重要的事情是从数据库中搜索数据的方式,如果我们尝试根据多个标准从多个表中获取一些信息,则应尽量减少所消耗的时间。如果我们的数据库中有大量数据,那么优化响应时间会变得越来越复杂,一些开发人员添加了存储过程,以便从 ORM 之后调用以进行优化,NHibernate 提供了几个查询 API,我们将在本文中描述 Criteria API 和类似的 QueryOver
。
背景
你需要有使用 Fluent NHibernate 的经验才能理解其中的区别。
查询
Criteria API
作为一种 ORM,NHibernate 操纵的是对象而不是表,此功能的使用简单、直观且可扩展。
要使用 Criteria
查询 API,我们需要从创建一个新的 NHibernate.ICriteria
实例开始,它与一个持久实体关联,并表示对其的查询。
这是 Person
实体的示例
ICriteria criteria = currentSession.CreateCriteria<Person>();
让我们操作这个标准来获得我们作为结果所需的内容。如果我们想获取所有 Persons
的列表
currentSession.CreateCriteria(typeof(T).List<T>() or we call our instance in this way: criteria.List<Person>();
如果我们例如需要按 Id
搜索 Person
Person person = currentSession.Get<Person>(id) or criteria.Get<Person>(id)
这些结果可以通过将限制应用于我们的 Criteria
查询来进行过滤。因此,我们使用 Restrictions
工厂类,该类定义了 ICriteria
接口上可用的许多方法,并将它们传递给 Add
方法。
让我们看看这个例子
Criteria.Add(Restrictions.Eq("Name", "Rayen"))
或者我们可以实例化一个类型为 IQueryCriterion
限制的新对象。
var restrictions = new Conjunction(); restrictions.Add (new LikeCriterion<A>(c => c.Name, “Rayen”, true, MatchingMode.Anywhere));
或者如果我们要相等,我们可以调用第二个方法
restrictions.Add(new EqualCriterion<A>(c => c.Name, "Rayen"));
这是方法 LikeCriterion
private LikeCriterion(Expression<Func<A, object>> propertyExpression, string value, bool insensitive, MatchingMode matchMode) { PropertyExpression = propertyExpression; Value = value; MatchMode = matchMode; Insensitive = insensitive; } public EqualCriterion(Expression<Func<A, object>> propertyExpression, object value) { PropertyExpression = propertyExpression; Value = value; } var persons = currentSession.CreateCriteria(typeof(Person)).Add(restrictions);
在这个例子中,我们介绍了可以分组的 Expression
的概念。
我们可以使用 NHibernate.Expression.Order
以这种方式在过滤后对结果进行排序。
var personOrdered = criteria.AddOrder( Order.Asc("Name") ).SetMaxResults(100).List<Person>();
我们可以使用使用工厂类 NHibernate.Expression.Projections IProjection
实例的 Projections
。
它通过调用方法 SetProjection()
来应用。
工厂方法允许通过标准和排序实例来引用投影值。
这是一个获取计数的示例。
public int GetCount(IQueryCriterion restrictions) { var criteria = _currentSession.CreateCriteria(typeof(T)) .SetProjection(Projections.RowCount return (int)criteria.UniqueResult(); }
Query Over API
Criteria
API 在动态构建查询以改进应用程序中的搜索方面非常强大。但正如我们在示例中看到的那样,属性在 criteria
查询中被硬编码。
因此,我们将使用 QueryOver
来增强 criteria
查询。
让我们重写之前的示例,但通过集成 QueryOver
。
criteria.List<Person>(); criteria.QueryOver<Person>().List(); var persons = currentSession.CreateCriteria(typeof(Person)).Add(restrictions); var persons = currentSession.QueryOver<Person>().Where(restrictions).List();
QueryOver
使用 Where
,它类似于 SQL 查询,它包含许多功能,例如,TransformUsing
使用提供的 IResultTransformer
转换结果。
IResultTransformer
是一个 Implementors
,它定义了将标准查询结果转换为实际的应用程序可见的查询结果列表的策略。
我们可以这样使用 OrderBy
我们在 IRepository
中有一个方法
IEnumerable<T> GetAllOrderBy(Expression<Func<T, bool>> restrictions, Expression<Func<T, object>> order, bool ascending = false);
实现将在 Repository
类中进行。
public IEnumerable<T> GetAllOrderBy(Expression<Func<T, bool>> restrictions, Expression<Func<T, object>> orderByProperty, bool ascending = false) { var query = currentSession.QueryOver<T>().Where(restrictions); return ascending ? query.OrderBy(orderByProperty).Asc.List() : query.OrderBy(orderByProperty).Desc.List(); }
其中 T
是 Person
。
这是在业务层中的调用,我们填写所有参数
var Persons = _personRepository.GetAllOrderBy(e => e.Name == "Rayen", e=>e.CreationTime, true);
有关更多详细信息,请查看 此链接。