c# - NHibernate Query<T>、Get<T> 和 Load<T> 的区别

标签 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 (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;
            }
        }
    }
}

甚至这样:

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;
            }
        }
    }
}

并向这个问题添加另一个问题,Query()QueryOver() 有何不同?

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

最佳答案

类似try to explain it is here

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

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

2) 然后,我们有 Get<TEntity>() ,这是按 ID 获取项目的最常见方式。它总是命中数据库,因为它的契约(Contract)说(get):

Return the persistent instance of the given entity class with the given identifier, or null if there is no such persistent instance

因此,要确定对象是否存在,必须命中 DB。

3) 最后,还有第三个契约(Contract) - Load<TEntity>() .它永远不会访问数据库来检查是否有这样的项目(具有提供的 ID):load() :

Return the persistent instance of the given entity class with the given identifier, assuming that the instance exists.

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

它将只是创建一个代理 - 使用提供的 ID 并且在该根/持有者实体的插入或更新期间,代理 ID 将用于创建正确的 SQL声明。

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

另见:

关于c# - NHibernate Query<T>、Get<T> 和 Load<T> 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37178455/

相关文章:

c# - 使用现有 key 向 Session 添加新对象是否会替换旧对象?

php - 插入多个表时的原子性

php - 我需要在更新 MYSQL 中的表后返回受影响行的主键。

php - fatal error : Call to a member function set_charset()

c# - 取消选择数据 GridView 中的所有行

c# - 在控制台应用程序下找不到 System.drawing 命名空间

c# - 推荐的 ILNumerics 优化包

java - 垃圾回收仅用于回收堆对象还是同时回收堆和堆栈中的对象?

SQL 连接多个表返回两列的产品

Asp.net WebAPI 给出错误没有找到与请求 URI 匹配的 HTTP 资源