0

I am trying to update an object after retrieving it from a database. This fires 2 queries , one for the select and the other for the update, is there any way of update an object using Fluent NHiberNate firing only one query ? My code is as below:

var userProfile = userProfileRepository
     .Find(x => x.ClientId == clientId)
     .FirstOrDefault();
/*  update UserProfile object here */
userProfileRepository.SaveOrUpdate(userProfile);

the SaveOrUpdate Method looks as such :

public bool SaveOrUpdate(T instance)
{
    using (var session = SessionManager.OpenSession())
    {
        using (var transaction = session.BeginTransaction())
        {
            session.SaveOrUpdate(instance);
            transaction.Commit();
        }
        return true;
    }
}
3
  • Well, you really should provide more details about the issue. 2 statements should be expectable, because you call Find and then Update. That should not be the issue. Or is it something else? Commented Jan 27, 2015 at 10:21
  • yup, its the same issue, on running profiler it sends 2 queries, one as a select and other for update, is there a conditional update for nhibernate which sends only one update statement Commented Jan 27, 2015 at 10:26
  • OK, so there are two selects during the update... that makes sense. My answer should give you some hints about the source of that, and how to solve it Commented Jan 27, 2015 at 10:27

2 Answers 2

2

In case that your issue is:

  • regardless of what I do, SaveOrUpdate() always sends SELECT then UPDATE

You should check the doc:

5.1.4.7. Assigned Identifiers

If you want the application to assign identifiers (as opposed to having NHibernate generate them), you may use the assigned generator. This special generator will use the identifier value already assigned to the object's identifier property. Be very careful when using this feature to assign keys with business meaning (almost always a terrible design decision).

Due to its inherent nature, entities that use this generator cannot be saved via the ISession's SaveOrUpdate() method. Instead you have to explicitly specify to NHibernate if the object should be saved or updated by calling either the Save() or Update() method of the ISession.

So, if your Fluent configuration sets the ID to be assigned - NHibernate has no other way then check if it

  • exists
  • or is new

because used method was SaveOrUpdate()

Solution(s)

1) Change the ID to be generated by DB or NHiberante 2) use explicit Update()

Sign up to request clarification or add additional context in comments.

1 Comment

I am not fully sure, what you'd like to get... because example of Udpate is just session.Update(instance). That should replace the session.SaveOrUpdate(isntance). That is enough for NHibernate to NOT issue the SELECT - the one which is checking: should be INSERT or UPDATE statement used... does it help?
0

Are you trying to create an

 UPDATE ... WHERE ... 

statement?

AFAIK the NHibernate way to do this, is to select the appropriate objects (using the WHERE clause), update the fields, and persist them again.

var tempObjects = _session.Query<myObject>.Where(o => o.Id > 500);

// update proxy objects
foreach (var o in tempObjects) 
{ 
   o.MyValue = updatedValue; 
}

// commit updated objects
_session.Update(tempObjects);

To be honest, we've used ISession.CreateSQLQuery ourselves. I hate using SQL in code because it breaks in refactoring, but if you must - here's how:

_session.CreateSQLQuery(
     @"UPDATE [MyTable] SET [MyValue]=:updatedvalue WHERE Id > 500")
    .SetParameter("updatedvalue", updatedValue)
    .ExecuteUpdate();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.