65.9K
CodeProject 正在变化。 阅读更多。
Home

NHibernate 在 Core 2.2 Framework 中的查询

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.67/5 (3投票s)

2018年12月28日

CPOL

3分钟阅读

viewsIcon

8051

在本文中,我们描述了使用 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();
}

其中 TPerson

这是在业务层中的调用,我们填写所有参数

var Persons = _personRepository.GetAllOrderBy(e => e.Name == "Rayen", e=>e.CreationTime, true);

有关更多详细信息,请查看 此链接

© . All rights reserved.