Criteria API关联查询

如果说HQL查询还有需要了解点SQL语法知识,并不是完全彻底面向对象查询,

那么Criterial API就是完全面向对象的查询方式。

 public IList<Customer> UseCriteriaAPI_GetCustomersWithOrders(DateTime orderDate)
{
return _session.CreateCriteria(typeof(Customer))
.Add(Restrictions.Eq("FirstName", "easy5")) //为本表查询添加查询参数
.CreateCriteria("Orders") //关联查询Order表开始,注意:“Oreders”是类Customer中关联到Order类的属性
.Add(Restrictions.Gt("OrderDate", orderDate))//OrderDate是Order类中的属性,不是数据库表Order的列名,如果是列名就不是面向对象编程了 .List<Customer>();
 }

我们使用CreateCriteria()在关联之间导航,很容易地在实体之间指定约束。

这里第二个CreateCriteria()返回一个ICriteria的新实例,并指向Orders实体的元素。

在查询中子对象使用子CreateCriteria语句,这是因为实体之间的关联我们在映射文件中已经定义好了。

还有一种方法使用CreateAlias()不会创建ICriteria的新实例。

预过滤

使用ICriteria接口的SetResultTransformer(IResultTransformer resultTransformer)方法返回满足特定条件的Customer。上面例子中使用条件查询,观察其生成的SQL语句并没有distinct,这时可以使用NHibernate.Transform命名空间中的方法或者使用NHibernate提供的NHibernate.CriteriaUtil.RootEntity、NHibernate.CriteriaUtil.DistinctRootEntity、NHibernate.CriteriaUtil.AliasToEntityMap静态方法实现预过滤的作用。那么上面的查询应该修改为:

public IList<Customer> UseCriteriaAPI_GetCustomersWithOrders(DateTime orderDate)
{
    return _session.CreateCriteria(typeof(Customer))
        .CreateCriteria("Orders")
        .Add(Restrictions.Gt("OrderDate", orderDate))
        .SetResultTransformer(new NHibernate.Transform.DistinctRootEntityResultTransformer()) //过滤重复项
        .List<Customer>();
}

这个例子从转换结果集的角度实现了我们想要的效果。

投影

调用SetProjection()方法可以实现应用投影到一个查询中。NHibernate.Criterion.Projections是Projection的实例工厂,Projections提供了非常多的方法,看看下面的截图

现在可以条件查询提供的投影来完成上面同样的目的:

public IList<Customer> UseCriteriaAPI_GetDistinctCustomers(DateTime orderDate)

{

IList<int> ids = _session.CreateCriteria(typeof(Customer))

.SetProjection(Projections.Distinct(Projections.ProjectionList()

.Add(Projections.Property("CustomerId"))

)

)

.CreateCriteria("Orders")

.Add(Restrictions.Gt("OrderDate", orderDate))

.List<int>();

return _session.CreateCriteria(typeof(Customer))

.Add(Restrictions.In("CustomerId", ids.ToArray<int>()))

.List<Customer>();

}

我们可以添加若干的投影到投影列表中,例如这个例子我添加一个CustomerId属性值到投影列表中,这个列表中的所有属性值都设置了Distinct投影,第一句返回订单时间在orderDate之后所有顾客Distinct的CustomerId,第二句根据返回的CustomerId查询顾客列表。达到上面的目的。这时发现其生成的SQL语句中有distinct。我们使用投影可以很容易的组合我们需要的各种方法。

范例:

  #region CriterialAPI 查询

         public IList<Customer> GetEntitysByDateTimeCriterialApi(DateTime dateTime)
{
IList<Customer> result = null;
ISession session = _sessionManager.GetSession(); result = session.CreateCriteria(typeof(Customer))
.CreateCriteria("Orders")
.Add(Restrictions.Gt("OrderDate", dateTime))
.List<Customer>(); return result;
} /// <summary>
/// 利用CreiteriaAPI进行的IN关键字的查询测试
/// </summary>
public IList<Customer> UseCreiteriaAPI_IN_Query()
{
ISession session = _sessionManager.GetSession();
// return session.CreateCriteria(typeof(Customer)).CreateCriteria("Orders").Add(Restrictions.Between("OrderDate", startDate, endDate))
// .List<Customer>(); object[] firstnames = { "zhang", "li" };
return session.CreateCriteria(typeof(Customer))
.Add(Restrictions.In("FirstName", firstnames))
.List<Customer>(); //return null;
} /// <summary>
/// 利用CreiteriaAPI进行的Or关键字的查询测试
/// </summary>
public IList<Customer> UseCreiteriaAPI_Or_Query()
{
ISession session = _sessionManager.GetSession();
String[] firstnames = { "zhang", "li" };
return session.CreateCriteria(typeof(Customer))
.Add(Restrictions.Or(Restrictions.Eq("FirstName", "zhang"), Restrictions.Eq("FirstName", "li")))
.List<Customer>();
} //CriteriaAPI的预过滤测试
public IList<Customer> UseCriteriaAPI_GetCustomersWithOrders(DateTime orderDate)
{
ISession session = _sessionManager.GetSession(); return session.CreateCriteria(typeof(Customer))
.CreateCriteria("Orders")
.Add(Restrictions.Gt("OrderDate", orderDate))
.SetResultTransformer(new NHibernate.Transform.DistinctRootEntityResultTransformer()) //Distinct--过滤重复项 .List<Customer>();
} //CriteriaAPI的Projection投影测试
public IList<Customer> UseCriteriaAPI_GetDistinctCustomers(DateTime orderDate)
{
ISession session = _sessionManager.GetSession(); IList<int> ids = session.CreateCriteria(typeof(Customer))
.SetProjection(Projections.Distinct(Projections.ProjectionList().Add(Projections.Property("CustomerId"))
))
.CreateCriteria("Orders")
.Add(Restrictions.Gt("OrderDate", orderDate))
.List<int>(); return session.CreateCriteria(typeof(Customer))
.Add(Restrictions.In("CustomerId", ids.ToArray<int>()))
.List<Customer>();
} //CriteriaAPI的Projection投影测试
public IList<Object[]> UseCriteriaAPI_GetDistinctCustomers2()
{
ISession session = _sessionManager.GetSession(); return session.CreateCriteria(typeof(Customer))
.SetProjection(Projections.ProjectionList()
.Add(Projections.Property("FirstName")).Add(Projections.Property("LastName")))
.List<Object[]>(); } #endregion

动态查询---关联查询:

         public IList<Customer> UseCriteriaApiAdvQuery(String firstName,
String lastName,
DateTime dateTime)
{
ICriteria criteria = _session.CreateCriteria("Customer");
if (null != firstName)
{
criteria.Add(Restrictions.Eq("FirstName", firstName));
}
if (null != lastName)
{
criteria.Add(Restrictions.Eq("LastName", lastName));
} if (null != dateTime)
{
//关联查询Order
// 注意:不是criteria.CreateCriteria("Order"),如果是,会抛异常:
//{"could not resolve property: Order of: Model.Customer"}
//而是criteria.CreateCriteria("Orders"),Orders是Customer类在关联的Order类的属性
criteria.CreateCriteria("Orders").Add(Restrictions.Eq("OrderDate", dateTime));
} return criteria.List<Customer>();
} 测试代码: [TestMethod]
public void TestUseCriteriaApiADvQuery()
{
CustomerService customerService = new CustomerService();
OrderService orderService = new OrderService(); Customer customer = new Customer()
{
FirstName = "Test",
LastName = "TestUseCriteriaApiADvQuery",
Age =
}; Order order1 = new Order()
{
OrderDate = DateTime.Now,
Customer = customer
}; customer.Orders.Add(order1);
customerService.Add(customer); Assert.IsNotNull(customerService.Find(customer.CustomerId));
Assert.IsNotNull(orderService.Find(order1.OrderId)); IList<Customer> customers =
customerService.UseCriteriaApiAdvQuery(customer.FirstName,
customer.LastName, order1.OrderDate); Assert.IsTrue(customers.Count > );
}

动态查询---模糊查询:

        #region CriterialAPI 动态+模糊查询

        public IList<Customer> UseCriteriaApiLikeQuery(String firstName,
String lastName)
{
ICriteria criteria = _session.CreateCriteria("Customer");
if (null != firstName)
{
//方式一:用原生的匹配字符,如:%
criteria.Add(Restrictions.Like("FirstName", "%" + firstName +"%"));
}
if (null != lastName)
{
//方式二:用MatchMode
criteria.Add(Restrictions.Like("LastName", lastName, MatchMode.Anywhere));
} return criteria.List<Customer>();
} #endregion 测试代码: #region 测试CriteriaAPI查询--动态 + 模糊查询 [TestMethod]
public void TestUseCriteriaApiLikeQuery()
{
CustomerService customerService = new CustomerService();
OrderService orderService = new OrderService(); Customer customer = new Customer()
{
FirstName = "Test",
LastName = "TestUseCriteriaApiLikeQuery",
Age =
}; Order order1 = new Order()
{
OrderDate = DateTime.Now,
Customer = customer
}; customer.Orders.Add(order1);
customerService.Add(customer); Assert.IsNotNull(customerService.Find(customer.CustomerId));
Assert.IsNotNull(orderService.Find(order1.OrderId)); IList<Customer> customers =
customerService.UseCriteriaApiLikeQuery(null,
"CriteriaApiLike"); Assert.IsTrue(customers.Count > );
} #endregion

排序:

        /// <summary>
/// 模糊查询+排序
/// </summary>
/// <param name="firstName"></param>
/// <param name="lastName"></param>
/// <returns></returns>
public IList<Customer> UseCriteriaApiLikeQueryAndDescOrder(String firstName,
String lastName)
{
ICriteria criteria = _session.CreateCriteria("Customer");
if (null != firstName)
{
//方式一:用原生的匹配字符,如:%
criteria.Add(Restrictions.Like("FirstName", "%" + firstName +"%"));
}
if (null != lastName)
{
//方式二:用MatchMode
criteria.Add(Restrictions.Like("LastName", lastName, MatchMode.Anywhere))
.AddOrder(NHibernate.Criterion.Order.Desc("CustomerId"));
} return criteria.List<Customer>();
} #endregion 测试代码: [TestMethod]
public void TestUseCriteriaApiLikeQueryAndDescOrder()
{
CustomerService customerService = new CustomerService();
OrderService orderService = new OrderService(); Customer customer1 = new Customer()
{
FirstName = "Test",
LastName = "TestUseCriteriaApiLikeQuery1",
Age =
}; Customer customer2 = new Customer()
{
FirstName = "Test",
LastName = "TestUseCriteriaApiLikeQuery2",
Age =
}; customerService.Add(customer1);
customerService.Add(customer2);
Assert.IsNotNull(customerService.Find(customer1.CustomerId));
Assert.IsNotNull(customerService.Find(customer2.CustomerId)); IList<Customer> customers =
customerService.UseCriteriaApiLikeQueryAndDescOrder(null, "CriteriaApiLike"); Assert.IsTrue(customer1.CustomerId < customer2.CustomerId);
Assert.IsTrue(customers[].LastName== customer2.LastName);
}

01-04-03【Nhibernate (版本3.3.1.4000) 出入江湖】Criteria API关联查询的更多相关文章

  1. 01-08-05【Nhibernate (版本3.3.1.4000) 出入江湖】NHibernate二级缓存:第三方MemCache缓存

    一.准备工作 [1]根据操作系统(位数)选择下载相应版本的MemCache, MemCache的下载和安装,参看: http://www.cnblogs.com/easy5weikai/p/37606 ...

  2. 01-03-02-2【Nhibernate (版本3.3.1.4000) 出入江湖】CRUP操作-Save方法的一些问题

    此文由于当时不知道NHibernate的Sava方法不是更新操作,不知道Save就是Add,造成如下荒唐的求证过程,但结论是对的 ,可报废此文,特此声明. NHibernate--Save方法: Cu ...

  3. 01-07-01【Nhibernate (版本3.3.1.4000) 出入江湖】并发控制

    Nhibernate 并发控制 [1]悲观并发控制 正在使用数据的操作,加上锁,使用完后解锁释放资源. 使用场景:数据竞争激烈,锁的成本低于回滚事务的成本 缺点:阻塞,可能死锁 [2]乐观并发控制: ...

  4. 01-08-03【Nhibernate (版本3.3.1.4000) 出入江湖】二级缓存:NHibernate自带的HashtableProvider之缓存管理

    http://www.cnblogs.com/lyj/archive/2008/11/28/1343418.html 管理NHibernate二级缓存 NHibernate二级缓存由ISessionF ...

  5. 01-08-04【Nhibernate (版本3.3.1.4000) 出入江湖】二级缓存:NHibernate自带的HashtableProvider之命名缓存

    http://www.cnblogs.com/lyj/archive/2008/11/28/1343418.html 可以在映射文件中定义命名查询,<query>元素提供了很多属性,可以用 ...

  6. 01-08-02【Nhibernate (版本3.3.1.4000) 出入江湖】二级缓存:NHibernate自带的HashtableProvider

    第一步骤:hibernate.cfg.xml文件补上如下配置: <?xml version="1.0" encoding="utf-8"?> < ...

  7. 01-08-01【Nhibernate (版本3.3.1.4000) 出入江湖】NHibernate中的一级缓存

    缓存的范围? 1.事务范围 事务范围的缓存只能被当前事务访问,每个事务都有各自的缓存,缓存内的数据通常采用相互关联的对象形式.缓存的生命周期依赖于事务的生命周期,只有当事务结束时,缓存的生命周期才会结 ...

  8. 01-08-01【Nhibernate (版本3.3.1.4000) 出入江湖】NHibernate中的三种状态

    以下属于不明来源资料: 引入 在程序运行过程中使用对象的方式对数据库进行操作,这必然会产生一系列的持久化类的实例对象.这些对象可能是刚刚创建并准备存储的,也可能是从数据库中查询的,为了区分这些对象,根 ...

  9. 01-06-01【Nhibernate (版本3.3.1.4000) 出入江湖】事务

    Nhibernate事务的使用: public void Add(Customer customer) { ISession session = _sessionManager.GetSession( ...

随机推荐

  1. gcc和arm-linux-gcc 头文件寻找路径【转】

    原文地址:http://blog.chinaunix.net/uid-29145190-id-3867605.html 在LINUX程序设计当中,经常会遇到头文件包含的问题,那么这些头文件到底在哪个路 ...

  2. Codevs 1105 过河

     时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond  题目描述 Description 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有 ...

  3. [Guava源码分析]Objects 和 ComparisonChain:帮助重写Object方法

    我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3874194.html,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体验 ...

  4. POJ 3624

    背包问题,在定容量的背包中放入物体求装满价值最大.因为每种物体数量只有1,故只有放与不放. #include<iostream> #include<cstring> #incl ...

  5. iOS Foundation框架简介 -1.常用结构体的用法和输出

    1.安装Xcode工具后会自带开发中常用的框架,存放的地址路径是: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.plat ...

  6. Linux常用命令操作说明(链接)

    1. Busybox下tftp命令使用详解 2. Linux中rc的含义 3. <Unix文件系统结构标准>(Filesystem Hierarchy Standard) 4. 用size ...

  7. [大牛翻译系列]Hadoop(3)MapReduce 连接:半连接(Semi-join)

    4.1.3 半连接(Semi-join) 假设一个场景,需要连接两个很大的数据集,例如,用户日志和OLTP的用户数据.任何一个数据集都不是足够小到可以缓存在map作业的内存中.这样看来,似乎就不能使用 ...

  8. WordPress 主题开发 - (五)WordPress 主题模板及目录结构 待翻译

    While the most minimal of WordPress Themes really only need an index.php template and a style.css fi ...

  9. 用户登录密码RSA加密后传输的实现,非明文密码传输

    在用户登录页面,用户输入密码后,在传送到服务器端时,为防止在密码传送过程中,被如360这种东东给拦截到, 需要在传送前对密码进行加密,然后再传送! 利用RSA加密,在客户端使用公钥对密码进行加密,在服 ...

  10. Python原始套接字编程

    在实验中需要自己构造单独的HTTP数据报文,而使用SOCK_STREAM进行发送数据包,需要进行完整的TCP交互. 因此想使用原始套接字进行编程,直接构造数据包,并在IP层进行发送,即采用SOCK_R ...