ここに何か欠けているかどうかはわかりません。基本的に、次の SQL ステートメントを実行するために Linq to Nhibernate を探しています。
update SomeTable
set SomeInteger = (SomeInteger + 1)
where SomeInteger > @NotSoMagicNumber
それを行う方法はありますか?
ありがとう!
ここに何か欠けているかどうかはわかりません。基本的に、次の SQL ステートメントを実行するために Linq to Nhibernate を探しています。
update SomeTable
set SomeInteger = (SomeInteger + 1)
where SomeInteger > @NotSoMagicNumber
それを行う方法はありますか?
ありがとう!
遅い回答ですが、現在は 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);
あなたの場合:
session.Query<SomeObject>()
.Update(i => new SomeObject { SomeInteger = i.SomeInteger + 1 });
NHibernate チームに感謝します。
ほとんどの (すべてではないにしても) LINQ プロバイダーと同様に、LINQ to NHibernate はデータの読み取りにのみ役立ちます。
LINQ を使用して NHibernate でやりたいことを実現するには、関連するすべてのオブジェクトを取得して、それぞれを更新する必要があります。何かのようなもの:
//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);
}
このすべての後、必ずセッションをフラッシュし、すべてをトランザクションにラップして、データベースの更新の数を最小限に抑えます。
とはいえ、データのサイズによっては、一括操作に NHibernate を使用する際にパフォーマンスの問題が発生する可能性があります。を使用するIStatelessSession
とその目的に役立つ場合がありますが、自分で試したことはありません。
UPDATEsession.Update
トランザクションでラップすると、セッションを実行またはフラッシュする必要がないことがわかります。
Linq (Linq to NHibernate ではなく、一般的な Linq) には、SQL のような一括更新動詞がありません。あなたのような一括更新ステートメントの効率が必要な場合は、SQL に固執します。