LINQ to NHibernate Bulk Equivalente Query di aggiornamento?
-
22-09-2019 - |
Domanda
Non sono sicuro se mi manca qualcosa qui. Fondamentalmente, io sono alla ricerca di LINQ to NHibernate per fare la seguente istruzione SQL:
update SomeTable
set SomeInteger = (SomeInteger + 1)
where SomeInteger > @NotSoMagicNumber
C'è un modo per farlo?
Grazie!
Soluzione
Linq (non LINQ to NHibernate, Linq in generale) non ha un aggiornamento verbo alla rinfusa come SQL trovi. Se è necessario l'efficienza della dichiarazione di aggiornamento di massa come la tua, mi piacerebbe solo rispettare SQL.
Altri suggerimenti
risposta in ritardo, ma ora esiste in NHibernate 5.0.
//
// Summary:
// Update all entities selected by the specified query. The update operation is
// performed in the database without reading the entities out of it.
//
// Parameters:
// source:
// The query matching the entities to update.
//
// expression:
// The update setters expressed as a member initialization of updated entities,
// e.g. x => new Dog { Name = x.Name, Age = x.Age + 5 }. Unset members are ignored
// and left untouched.
//
// Type parameters:
// TSource:
// The type of the elements of source.
//
// Returns:
// The number of updated entities.
public static int Update<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, TSource>> expression);
Nel tuo caso:
session.Query<SomeObject>()
.Update(i => new SomeObject { SomeInteger = i.SomeInteger + 1 });
Grazie squadra NHibernate!
Come la maggior parte (se non tutti) i fornitori di LINQ, LINQ to NHibernate viene solo in utile in lettura dei dati.
Per ottenere ciò che si vuole fare in NHibernate con l'aiuto di LINQ, si vuole prendere tutti gli oggetti rilevanti e aggiornare ogni uno. Qualcosa di simile:
//NHibernate session initialisation & finalisation skipped for brevity
var relevantObjects = from i in session.Linq<SomeObject>()
where i.SomeInteger > notSoMagicNumber
select i;
foreach (SomeObject item in relevantObjects)
{
i.SomeInteger++;
session.Update(item);
}
Assicurati di lavare la sessione dopo tutto questo, e avvolgere il tutto in una transazione per ridurre al minimo il numero di aggiornamenti del database.
Detto questo, a seconda della dimensione dei dati, si può incorrere in problemi di prestazioni nell'utilizzo di NHibernate per operazioni di massa. L'utilizzo di un IStatelessSession
può contribuire a tale scopo, ma non l'ho provato io stesso.
Aggiorna scopre se avvolgetelo in una transazione, non è necessario fare session.Update
o sciacquare la sessione.