C# NHibernate查询之间的差异<;T>;,获取<;T>;和负载<;T>;

C# NHibernate查询之间的差异<;T>;,获取<;T>;和负载<;T>;,c#,asp.net,database,linq,nhibernate,C#,Asp.net,Database,Linq,Nhibernate,我想找出在执行以下操作时使用这三种从数据库获取数据的方法的区别: public T GetById(int id) { using (var db = Database.Session) { using (var t = db.BeginTransaction()) { try { return db.Get<T>(id); } catch (Excepti

我想找出在执行以下操作时使用这三种从数据库获取数据的方法的区别:

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){
使用(var db=Database.Session){
使用(var t=db.BeginTransaction()){
试一试{
返回db.Get(id);
}
捕获(例外){
如果(!t.wascommited){
t、 回滚();
}
投掷;
}
}
}
}

public T GetById(int-id){
使用(var db=Database.Session){
使用(var t=db.BeginTransaction()){
试一试{
返回Query().First(x=>x.Id==Id);
//或者类似的
//return Query().Where(x=>x.Id==Id).FirstOrDefault();
//或
//返回QueryOver()。其中(x=>x.Id==Id);
}
捕获(例外){
如果(!t.wascommited){
t、 回滚();
}
投掷;
}
}
}
}
或者甚至是这样:

public T GetById(int id) {
    using (var db = Database.Session) {
        using (var t = db.BeginTransaction()) {
            try {
                return db.Load<T>(id);
            }
            catch (Exception) {
                if (!t.WasCommitted) {
                    t.Rollback();
                }
                throw;
            }
        }
    }
}
public T GetById(int-id){
使用(var db=Database.Session){
使用(var t=db.BeginTransaction()){
试一试{
返回db.Load(id);
}
捕获(例外){
如果(!t.wascommited){
t、 回滚();
}
投掷;
}
}
}
}
在这个问题上添加另一个问题,
Query()
QueryOver()
有何不同

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

Query()与QueryOver()有何不同

QueryOver是标准的强类型版本,并且更特定于NHibernate。几乎所有你在iCiteria能做的事情都可以通过QueryOver来完成。在ICriteria NH2的黄金时期,你总是需要施放,因此这就是为什么现在你需要在链的末端施放回整数

LINQ(查询)是一种标准的查询方法,它在IQueryable上工作,不需要显式引用NHibernate,可以被视为更不确定ORM,因此遵循LINQ标准。正如您正确指出的,当您在结果中选择customNumber时,不需要强制转换为int。

类似

一般来说,我们有三种方法可以通过ID从DB中获取实例

1) 查询——这就是我们使用QueryOverAPI(原生NHibernate语言)或查询(MS LINQ API的实现)的地方。这些查询总是命中数据库(或缓存),可以加载完整的根对象,获取一些关系,或者只是投影(只有少数列/属性转换为某些DTO)

2) 然后,我们有了
Get()
,这是通过ID获取项目的最常见方式。它总是命中DB,因为它的合同规定():

返回具有给定标识符的给定实体类的持久实例,如果没有此类持久实例,则返回null

所以,为了确定对象是否存在,必须命中DB

3) 最后,还有第三个契约-
Load()
。它永远不会点击DB来检查是否存在这样的项目(提供ID)::

假设实例存在,返回具有给定标识符的给定实体类的持久实例

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

它将创建一个具有提供ID的代理-,在插入或更新该根/持有者实体的过程中,该代理ID将用于创建正确的SQL语句

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

另见:

  • NHibernate——
也许能帮到你?
public T GetById(int id) {
    using (var db = Database.Session) {
        using (var t = db.BeginTransaction()) {
            try {
                return db.Load<T>(id);
            }
            catch (Exception) {
                if (!t.WasCommitted) {
                    t.Rollback();
                }
                throw;
            }
        }
    }
}