2016-04-13 4 views
1

私はDevart.Data.Linq.ChangeConflictException: Row not found or changedの断続的な出現を調べています。* Devartを使用していない* ChangeConflictExceptionを取得しています

私はconcurrency conflictsのDevartの記事を読んできました。ちょうど出発点として、同時性の競合を再現しようとしています。含まれているMSベースのLINQクラスを使用することは簡単です(以下のコード構造を使用するとうまくいきます)。しかし、たとえ記事の例に従えば、私は例外を生成することはできません。私は、ADOの両方を使用して

  • を試してみましたが、新しいコンテキストでLinqConnectを使用して(このテスト中にインジェクション攻撃を心配していない)を以下に示す単純化されたADOクエリ
  • を使用して自分の記事
  • に示すとおりにクエリをparamaterised (彼らの記事でも示唆されている)。
  • デバッガで実行を一時停止し、MySQL Workbenchを使用して手動でテーブルを更新します。

これは私が使用していたテストコードです:

public static void MySqlTest() 
{ 
    using (MySqlDataContext db = new MySqlDataContext()) 
    { 
     Customer customer = db.Customers.First(c => c.Username.Equals("ian2")); 

     MySqlAdoChange(db.Connection); 
     //MySqlLinqConnectChange(); 

     customer.Address1 = "Original change" + DateTime.UtcNow.Ticks; 
     db.SubmitChanges(); 
    } 
} 

public static void MySqlAdoChange(DbConnection connection) 
{ 
    connection.Open(); 
    var command = connection.CreateCommand(); 
    command.CommandText = "UPDATE customers SET Address1 = 'Conflicting change" + DateTime.UtcNow.Ticks + "' WHERE Username = 'ian2'"; 
    command.ExecuteNonQuery(); 
} 

public static void MySqlLinqConnectChange() 
{ 
    using (MySqlDataContext db = new MySqlDataContext()) 
    { 
     Customer customer = db.Customers.First(c => c.Username.Equals("ian2")); 
     customer.Address1 = "Conflicting change" + DateTime.UtcNow.Ticks; 
     db.SubmitChanges(); 
    } 
} 

を二重に奇妙である何が価値がデータベース交互に2間のに保存されたということです! 一意性を保証するために、DateTimeティックを最後に追加する必要がありました。そうしないと、更新が最適化され、現在アクティブではない値に更新されました。

誰でもこの動作を説明できますか? ChangeConflictExceptionを生成できないのはなぜですか?

答えて

1

まず、あなたのコード例では、あなたがMySqlTest機能でPhoneフィールドを更新することをノートが、MySqlAdoChange機能でAddress1フィールドなので、任意の競合が発生することはできません。

ただし、これを修正しても、おそらく更新の競合は発生しません。 Customerクラスのソースコードを参照すると、Phoneプロパティで、UpdateCheck = UpdateCheck.Never(これはhttps://www.devart.com/linqconnect/docs/MemberMapping.htmlを参照)の列属性で装飾されていることがよくわかります。デフォルトでは、LinqConnectはフィールドの更新の競合をチェックしません。確認するフィールドには、UpdateCheck = UpdateCheck.AlwaysまたはUpdateCheck.WhenChangedを付けて確認する必要があります。もちろん、ソースコードを直接変更するのではなく、モデルデザイナーでそのプロパティを変更する必要があります。

+0

あなたはもちろん、Phone vs Addressについても当然です。もともと私はPhoneフィールド(実際にはテキストフィールドですが、明らかにそうではありません)でテストしていましたが、Addressを使って物事を「単純化」し、SOの質問を正しく更新しませんでした。情報のおかげであなたが提案する属性を調べます。私はあなたが興味を持っているかもしれない別の賞金の質問[ここ](http://stackoverflow.com/questions/36586779/devart-changeconflictexception-but-values-still-written-to-database?lq=1)を持っています、この1つより大きな問題の一部にすぎません。 – Ian

+0

あなたは2回目のスポットライトを受けていました。私の変数は 'UpdateCheck = UpdateCheck.Never'属性で飾られた_all_(ID PKを除いたもの)でした。それを削除すると、期待どおりの例外が生成されます。ありがとう、私の問題の半分を解決する。しかし、私の他の 'ChangeConflictException'問題はさらに困惑しています。 – Ian

関連する問題