Is there any other way than with HQL, to bulk update with Nhibernate?

Asked

Viewed 497 times

3

I need to do a routine that will set one flag in several records that meet some requirements, and would like to keep this in control of the Nhibernate.

However, I couldn’t find any way to do a mass update (update batch), with the compileable and repeatable resources of Fluentnhibernate (and Nhibernate), I wouldn’t want to leave for HQL, where I’ve realized it’s possible, but would lose all the advantages of refactoring.

What I would like to do is something very simple, similar to this in SQL:

UPDATE TABELAFLAGS SET COLUMNFLAG1 = 1 WHERE COLUMNFLAG2 = 2 AND COLUMNFLAG3 = 3

That would be so in HQL:

Session.CreateQuery(
@"update ClassFlags set flag1 = :p1 where flag2 = :p2 and flag3 = :p3"
).SetInt32("p1", 1).SetInt32("p2", 2).SetInt32("p3", 3).ExecuteUpdate();

It is possible to do this efficiently with Session.Update() or some other method?

  • is C# with Fluentnhibernate ?

  • 1

    Yes, Nhibernate is C#, in java is Hibernate. I will add the tag.

  • 1

    Yeah, I just wanted to make sure it was with C# @Fernando

2 answers

3

In order for you to do a multi-line update you need to rescue these lines first, from the way sequinte:

Model Class

public class Flags
{
    public virtual int Id { get; set; }
    public virtual int Quantidade { get; set; }
    public virtual int Serie { get; set; }
}
//Mapeamento
public class FlagsMap: FluentNHibernate.Mapping.ClassMap<Flags>
{
    public FlagsMap()
    {
        Table("flags");
        Id(x => x.Id).Column("id").GeneratedBy.Identity().Not.Nullable();
        Map(x => x.Quantidade).Column("quantidade").Not.Nullable();
        Map(x => x.Serie).Column("serie").Not.Nullable();
    }
}

Search Method

public IQueryable<T> Query(Expression<Func<T,bool>> Where)
{
    return Session.CreateCriteria<T>().List<T>().AsQueryable<T>().Where<T>(Where);
}

Code, to bring the number id 1 and 2 and changing the amount to 0

int[] Ids = new int[2]{1,2};
var lista = Query(x=>Ids.Contains(x.Id)).ToList();
for(int i = 0; i < lista.Count(); i++){
        lista[i].Quantidade = 0;
}
Session.Flush();

That is, bringing the data in cache and changing your data and giving a Session.Flush(), it updates all the lines changed, so you don’t need to use HQL. It works the same way as most Orms.

Note: I removed this example from a very well structured Repository layer and put only what was needed for this answer

  • 1

    Will this approach perform well on a large scale, similar to implementing with HQL? Put in my tests here verified that it will do a UPDATE for every record, but still it seemed very efficient. It runs all the updates in a single transaction (transaction)?

  • 1

    If you search 100 records and change 10 records and update 10 records, if you search 100 records and change them all, it uses the current transaction for change! In relation to performance will depend a lot on various scenarios but, usually, we do so without the HQL. Reinforcing, it is very efficient, functional and performative will depend on scenarios !!!

0


Currently with Nhibernate 5.0 the following functionality has been included: Modifying entities Inside the database, implementing something similar to the one sought in the question: Updating entities, which would be the possibility of a similar implementation to that:

using NHibernate.Linq;
...    

session.Query<Cat>()
    .Where(c => c.BodyWeight > 20)
    .UpdateBuilder()
    .Set(c => c.BodyWeight, 20)
    .Update();

Which would be equivalent to an SQL like:

UPDATE Cat
SET BodyWeight = 20
WHERE BodyWeight > 20;

Browser other questions tagged

You are not signed in. Login or sign up in order to post.