2016-05-12 35 views
3

我想找到使用做这样的事情时,从数据库中获取数据的这三种方式的区别:NHibernate的差异,获取<T>和负载<T>

public T GetById(int id) { 
    using (var db = Database.Session) { 
     using (var t = db.BeginTransaction()) { 
      try { 
       return db.Get<T>(id); 
      } 
      catch (Exception) { 
       if (!t.WasCommitted) { 
        t.Rollback(); 
       } 
       throw; 
      } 
     } 
    } 
} 

public T GetById(int id) { 
    using (var db = Database.Session) { 
     using (var t = db.BeginTransaction()) { 
      try { 
       return Query<T>().First(x=>x.Id == id); 
       //or something like 
       //return Query<T>().Where(x=>x.Id == id).FirstOrDefault(); 
       //or 
       //return QueryOver<T>().Where(x=>x.Id == id).FirstOrDefault; 
      } 
      catch (Exception) { 
       if (!t.WasCommitted) { 
        t.Rollback(); 
       } 
       throw; 
      } 
     } 
    } 
} 

甚至这样说:

​​

另外还有一个问题,Query()QueryOver()有什么不同?

我在这里阅读了一些在stackoverflow的答案,但由于其中大部分是关于开始使用Linq和NHibernate 3,我想知道今天的情况如何。

+0

也许[这](https://ayende.com/blog/3988/nhibernate-the-difference-between- get-load-and-query-by-id)可以帮助你吗? – SeM

回答

2

类似try to explain it is here

一般来说我们有三种方式可以由它的编号来获得从数据库实例。

1)查询 - 这是我们使用QueryOver API(原生NHibernate语言)或查询(实现MS LINQ API)的地方。这些查询总是打DB(或高速缓存),能够加载全根对象,获取一些关系,或只是投影(仅几列/属性转换成一些DTO)

2)然后,我们有Get<TEntity>(),其目的是作为如何通过ID获取物品的最常见方式。它总是命中DB因为合同其说(get):

返回与给定的标识符指定的实体类,或的持久化实例,如果不存在这样的持久化实例

因此,为了确保该对象是否存在,必须击中数据库。

3)最后,还有第三个合同-Load<TEntity>()。它永远不会打DB,以检查是否有这样一个项目(与提供的ID)load()

返回与给定的标识符指定的实体类的持久化实例,假设实例存在。

如果我们有一个参考ID,并且我们知道它确实存在,我们应该使用Load<TEntity>()

它将只是创建一个代理 - 与设置ID和根/保持器实体的插入或更新的过程中,代理ID将被用于创建正确的SQL语句。

总结:Get()Load()是有我们的原因。它们旨在支持不同的场景。

参见:

1

Query()与QueryOver()的区别?

QueryOver是Criteria的强类型版本,更具体的NHibernate。几乎任何你可以在ICriteria中做的事情都可以使用QueryOver完成。在ICriteria NH2的黄金时段,你总是必须施放,因此这就是为什么现在你需要在链的末尾回到int。

LINQ(查询)是一种标准的查询方法,适用于IQueryable,不需要显式引用NHibernate,可以考虑更多的ORM不可知,因此遵循linq标准。正如你正确地指出,你不需要投入到一个int,因为你正在选择结果customNumber。