Is there any non-HQL way to bulk update with NHibernate?

3

I'm having a routine that will set a flag in several records that meet certain requirements, and I'd like to keep that in control of NHibernate .

However, I have not found any way to do a bulk update (update batch), with the FluentNHibernate compileable and refactorable NHibernate I would not want to go to HQL , where I already realized that it is possible, but I 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

What would be like this 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();

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

    
asked by anonymous 20.05.2014 / 21:48

2 answers

0

NHibernate 5.0 has been added to : Modifying entities inside the database , which implements something similar to the one searched for in the question: Updating entities , which would be the possibility of a similar implementation like this:

using NHibernate.Linq;
...    

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

That would be equivalent to a SQL like:

UPDATE Cat
SET BodyWeight = 20
WHERE BodyWeight > 20;
    
19.12.2017 / 11:43
3

For you to do an update in several lines you need to redeem these lines first, in the following way:

Template

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

Coding, to bring the ID of number 1 and 2 and changing the quantity 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, by caching the data and changing its data and giving a Session.Flush() , it does an update on all changed rows, so you do not have to use HQL. It works the same way as most ORMs.

Note: I removed this example from a layer with a well-structured Repository and put only what was needed for this response     

21.05.2014 / 18:52