2016-08-04 10 views
4

私はユーザーがアイテムを好きになることができるWebアプリケーションを持っています。それぞれのアイテムは、彼が得た全好きなもののプロパティを持っています。ASP.NET |エンティティフレームワーク、競合状態

多くのユーザーが同時に同じアイテムを好きなときに競合状態によってSQLで間違った値を受け取っているときに問題が発生します。

一時的な解決策として、コントローラーコンストラクターで、キューに対して作業するワーカースレッドを作成しました。このとき、/嫌いなリクエストのアイテムが受信されたときに、このリクエストをキューに入れています。ワーカースレッドは値をデキューし、itemidをtotalcountにマップする辞書を更新します。

ワーカースレッドは、結果を1分ごとに1回データベースを更新します。

サイド質問:context.SaveChanges()オブジェクトの変更内容のみを保存しますか?またはオブジェクトのすべてのプロパティを保存しますか?

私はこの解決策が適切ではないと感じています。そのような問題に対処する最善の方法は何ですか?読み取りおよび書き込みが発生したときに

+1

あなたは(そのシリアライズと呼ばれるSQL Serverの中)syncronized分離レベルを使用してデータベースを更新する必要があります。しかし、プロバイダーに言及していないので、不可能かもしれません(つまり、Msアクセスを使用している場合)。 – Igor

+1

'context.savechangesはオブジェクトの変更内容だけを保存しますか?またはそれはオブジェクトのすべてのプロパティを保存します - それは依存します。オブジェクト状態を変更に設定すると、オブジェクト全体が汚れていると認識されるため、すべてが保存されます。コンテキストから既存のオブジェクトを取得し、1つまたは複数のプロパティを更新し、変更したものだけを保存すると、データベースに再び保存されます。 – Igor

+0

Hey Igor!同期分離レベルとは何を意味しますか?どのように私は1つを定義するのですか?私はSqlデータベース(紺碧でホストされている)を使用しています –

答えて

1

あなたはRepeatableReadトランザクションスコープ魔女ロックデータを使用することができます。

using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead })) 
{ 
    ... 
    context.SaveChanges(); 
    scope.Complete(); 
} 

Entity Frameworkのトラックエンティティのフィールドが変更とのみに変更されたものを更新するために、SQLコードを生成します。あなたは明示的に一つだけエンティティプロパティを更新し、その他の変更を無視するように指定することがあります。

context.Entry(entity).State = EntityState.Unchanged; 
context.Entry(entity) 
     .Property(c => c.entityField).IsModified = true; 

あなたがコンテキストにオブジェクトを添付するときにも、それが有用であることができます。

context.Attach(entity); 
context.Entry(entity) 
     .Property(c => c.entityField).IsModified = true; 

Attachがエンティティを置いているためとコンテキストはUnchanged州のプロパティです。パフォーマンスと同時実行の問題のため

0

が優れているExecuteSqlCommandを使用している:

string sql = "UPDATE Table SET LikeCount = LikeCount+1 WHERE Id={0}"; 
using (var context = new BloggingContext()) 
{ 
    context.Database.ExecuteSqlCommand(sql, new SqlParameter("@Id", id)); 
}