查询<T>、Get<T>之间的NHibernate区别和负载 T [英] NHibernate difference between Query<T>, Get<T> and Load<T>

查看:19
本文介绍了查询<T>、Get<T>之间的NHibernate区别和负载 T的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

public T GetById(int id) {使用(var db = Database.Session){使用 (var t = db.BeginTransaction()) {尝试 {返回 db.Get(id);}捕获(异常){如果(!t.WasCommitted){t.回滚();}扔;}}}}

public T GetById(int id) {使用(var db = Database.Session){使用 (var t = db.BeginTransaction()) {尝试 {返回查询().First(x=>x.Id == id);//或类似的东西//返回查询().Where(x=>x.Id == id).FirstOrDefault();//或者//返回QueryOver().Where(x=>x.Id == id).FirstOrDefault;}捕获(异常){如果(!t.WasCommitted){t.回滚();}扔;}}}}

甚至这样:

public T GetById(int id) {使用(var db = Database.Session){使用 (var t = db.BeginTransaction()) {尝试 {返回 db.Load(id);}捕获(异常){如果(!t.WasCommitted){t.回滚();}扔;}}}}

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

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

解决方案

类似尝试解释一下>

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

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

2) 然后,我们有 Get(),这是最常用的通过 ID 获取项目的方法.它总是命中 DB 因为它的合同说 (get):

<块引用>

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

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

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

<块引用>

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

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

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

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

另见:

I'd like to find the difference in using these three ways of getting data from the database when doing something like:

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

or

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

or even this way:

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

And adding another question to this one, how the Query() differs from QueryOver()?

I've read some answers here in stackoverflow but since the majority of them was about the starting of using Linq, and NHibernate 3, I'd like to know how is the scenario today.

解决方案

Similar try to explain it is here

In general we've got three ways how to get an instance from DB by its ID.

1) Querying - That is where we use QueryOver API (native NHibernate language) or Query (implementation of the MS LINQ API). These queries always hit the DB (or cache) and could load full root object, fetch some relations, or be just projections (only few columns/properties converted into some DTO)

2) Then, we have Get<TEntity>(), which was intended as the most common way how to get item by ID. It always hits DB because its contract says (get):

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

So, to be sure that object exists or not, DB must be hit.

3) Finally, there is a third contract - Load<TEntity>(). It will never hit DB to check if there is such an item (with provided ID): load():

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

If we've got a reference ID, and we know that it does exist we should use the Load<TEntity>().

It will just create a proxy - with provided ID and during the INSERT or UPDATE of that root/holder entity, the proxy ID will be used to create correct SQL Statement.

Summary: Get() and Load() are there for us for a reason. They were designed to support different scenarios.

See also:

这篇关于查询&lt;T&gt;、Get&lt;T&gt;之间的NHibernate区别和负载 T的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆