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!

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top