Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
793 views
in Technique[技术] by (71.8m points)

c# - NHibernate difference between Query<T>, Get<T> and Load<T>

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...