2012-10-04 10 views
10

EFのデフォルトでは、更新が失われる同時実行制御(最後の書き込みが勝つ)はありません。 RowVersion列でConcurrencyMode = Fixedを設定すると、オプティミスティック同時実行チェックを強制的に実行できます。設定を自動化する方法ConcurrencyMode =すべてのRowVersion列で修正済みですか?

どのようにして設定を自動化できますか?ConcurrencyMode =すべてのテーブルのRowVersion列で修正されましたか? データベースからEFモデルを再作成するときにこれを手動で行う必要があるため、同時実行制御なしで稼働していることを忘れる恐れがあります。

+1

XSLTのために働いていますか? –

+1

私は慣習で何かを逃した何か組み込みのものを望んでいました。これは標準的な要件です。ほとんどのDBアプリケーションでは、並行性の制御が必要です。 –

+1

なぜこのような基本機能が存在しないのか分かりません。 EF CodePlexで機能要求を出しました[ConcurrencyMode = Fixed](http://entityframework.codeplex.com/workitem/588) –

答えて

6

これは、モハメド・カセムによって答えに似ていますが、私は、設計者が属性の順序を変更することができるよう、代わりに置き換える文字列の検索と置換属性XMLを使用するコード、または他のプロパティを更新しました異なる値を持つことができます。

これをFixVersionColumnConcurrencyMode.csとして保存し、csc FixVersionColumnConcurrencyMode.csを実行し、結果のFixVersionColumnConcurrencyMode.exeを.edmxファイルと同じフォルダに実行します。また、プロジェクトのポストビルドを実行させることもできます。

+0

最初のwhere句を 'el.Attribute(" Name ")!= null && el.Attribute(" Name ")に変更することを検討してください。列名。 –

1

私は自分で作ったわけではありませんが(しかし、おそらくすぐには必要です)、.edmxからコードを生成するためのツールを変更することは可能です。

HereはVS2008用の記事です。私はプロセスがVS2010とVS2012についてほぼ同じになると思う。

しかし、これでConcurrencyModeをどのように使ってもうまくいくかどうかはわかりません。

4

EF6では、データベースからモデルを作成するときに、ConcurrencyMode = Rowversion列で固定されます。Designer: Automate setting ConcurrencyMode=Fixed on rowversion columnsを参照してください。それまでは手動で行う必要があります。

+1

残念ながら、RoMillerによる最新のステータス投稿は「私たちはまだコードベースをオープンソースに変換しているため、EF6のデザイナーにはほとんど変更を加えていません。次のリリースでこのバグを考慮してください。 " – Rick

4

は、この機能はEF 5またはEF 6

の周りになるだろうされていないように私は、DBファーストを生成した後EDMXを更新するために迅速なコンソールアプリケーションを手早くようです。

ファイルをedmxファイルの同じディレクトリにドロップし、すべての再生成後に実行してください。

は、次の列のいずれかのために動作します:

RowVersion timestamp NOT NULL 
rowversion timestamp NOT NULL 
RowVer  timestamp NOT NULL 
rowver  timestamp NOT NULL 

あなたはhttps://dl.dropbox.com/u/3576345/EFConcurrencyFixed.exe

ここでコンソールアプリを取得したり、独自のコンソールアプリケーションのコードのこの部分を使用することができます。

class Program 
{ 
    static Dictionary<string, string> replacements = new Dictionary<string, string>() 
    { 
     { "<Property Type=\"Binary\" Name=\"RowVersion\" Nullable=\"false\" MaxLength=\"8\" FixedLength=\"true\" annotation:StoreGeneratedPattern=\"Computed\" />", 
      "<Property Type=\"Binary\" Name=\"RowVersion\" Nullable=\"false\" MaxLength=\"8\" FixedLength=\"true\" annotation:StoreGeneratedPattern=\"Computed\" ConcurrencyMode=\"Fixed\" />"}, 

     { "<Property Type=\"Binary\" Name=\"rowversion\" Nullable=\"false\" MaxLength=\"8\" FixedLength=\"true\" annotation:StoreGeneratedPattern=\"Computed\" />", 
      "<Property Type=\"Binary\" Name=\"rowversion\" Nullable=\"false\" MaxLength=\"8\" FixedLength=\"true\" annotation:StoreGeneratedPattern=\"Computed\" ConcurrencyMode=\"Fixed\" />"}, 

     { "<Property Type=\"Binary\" Name=\"RowVer\" Nullable=\"false\" MaxLength=\"8\" FixedLength=\"true\" annotation:StoreGeneratedPattern=\"Computed\" />", 
      "<Property Type=\"Binary\" Name=\"RowVer\" Nullable=\"false\" MaxLength=\"8\" FixedLength=\"true\" annotation:StoreGeneratedPattern=\"Computed\" ConcurrencyMode=\"Fixed\" />"}, 

     { "<Property Type=\"Binary\" Name=\"rowver\" Nullable=\"false\" MaxLength=\"8\" FixedLength=\"true\" annotation:StoreGeneratedPattern=\"Computed\" />", 
      "<Property Type=\"Binary\" Name=\"rowver\" Nullable=\"false\" MaxLength=\"8\" FixedLength=\"true\" annotation:StoreGeneratedPattern=\"Computed\" ConcurrencyMode=\"Fixed\" />"}, 
    }; 

    static void Main(string[] args) 
    { 
     // find all .edmx 
     string directoryPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); 
     foreach (var file in Directory.GetFiles(directoryPath)) 
     { 
      // only edmx 
      if (!file.EndsWith(".edmx")) 
       continue; 

      // read file 
      var fileContents = System.IO.File.ReadAllText(file); 

      // replace lines 
      foreach (var item in replacements) 
       fileContents = fileContents.Replace(item.Key, item.Value); 

      // overwite file 
      System.IO.File.WriteAllText(file, fileContents); 
     } 
    } 
} 
0

私はConcurrencyModeを手動で設定して退屈だから、私はそれを自動化するための小さなユーティリティを書きました。特定のタイプ(タイムスタンプ/ロウ・バージョン)または特定の正規表現パターンに一致するカラム名のためにモードを設定するためにそれを使うことができます。

http://blog.wezeku.com/2014/04/28/fixefconcurrencymodes/

あなたはEDMXファイルに一度ConcurrencyMode=Fixedを追加したhttps://github.com/wezeku/FixEFConcurrencyModes

1

、その後、後であなたがコードでチェックインする前に、あなたのモデルを更新するたびに、(あなたには、いくつかのバージョン管理ライフTFSのセットアップを持っていると仮定します)最新のバージョンと比較し、それに応じて変更をマージします。この方法では、手動ですべての単一行を更新する必要はありません。最善の方法ではなく、少なくとも手動で行うよりも優れています。

0

これは、モハメド・カセムの答えですが、それはあなたのビルドプロセスにEF6

static Dictionary<string, string> replacements = new Dictionary<string, string>() 
    { 
     { "<Property Name=\"RowVersion\" Type=\"Binary\" Nullable=\"false\" MaxLength=\"8\" FixedLength=\"true\" annotation:StoreGeneratedPattern=\"Computed\" />", 
      "<Property Name=\"RowVersion\" Type=\"Binary\" Nullable=\"false\" MaxLength=\"8\" FixedLength=\"true\" annotation:StoreGeneratedPattern=\"Computed\" ConcurrencyMode=\"Fixed\" />"}, 

     { "<Property Name=\"rowversion\" Type=\"Binary\" Nullable=\"false\" MaxLength=\"8\" FixedLength=\"true\" annotation:StoreGeneratedPattern=\"Computed\" />", 
      "<Property Name=\"rowversion\" Type=\"Binary\" Nullable=\"false\" MaxLength=\"8\" FixedLength=\"true\" annotation:StoreGeneratedPattern=\"Computed\" ConcurrencyMode=\"Fixed\" />"}, 

     { "<Property Name=\"RowVer\" Type=\"Binary\" Nullable=\"false\" MaxLength=\"8\" FixedLength=\"true\" annotation:StoreGeneratedPattern=\"Computed\" />", 
      "<Property Name=\"RowVer\" Type=\"Binary\" Nullable=\"false\" MaxLength=\"8\" FixedLength=\"true\" annotation:StoreGeneratedPattern=\"Computed\" ConcurrencyMode=\"Fixed\" />"}, 

     { "<Property Name=\"rowver\" Type=\"Binary\" Nullable=\"false\" MaxLength=\"8\" FixedLength=\"true\" annotation:StoreGeneratedPattern=\"Computed\" />", 
      "<Property Name=\"rowver\" Type=\"Binary\" Nullable=\"false\" MaxLength=\"8\" FixedLength=\"true\" annotation:StoreGeneratedPattern=\"Computed\" ConcurrencyMode=\"Fixed\" />"}, 

     { "<Property Name=\"RowVersion\" Type=\"Binary\" MaxLength=\"8\" FixedLength=\"true\" annotation:StoreGeneratedPattern=\"Computed\" />", 
      "<Property Name=\"RowVersion\" Type=\"Binary\" MaxLength=\"8\" FixedLength=\"true\" annotation:StoreGeneratedPattern=\"Computed\" ConcurrencyMode=\"Fixed\" />"}, 

     { "<Property Name=\"rowversion\" Type=\"Binary\" MaxLength=\"8\" FixedLength=\"true\" annotation:StoreGeneratedPattern=\"Computed\" />", 
      "<Property Name=\"rowversion\" Type=\"Binary\" MaxLength=\"8\" FixedLength=\"true\" annotation:StoreGeneratedPattern=\"Computed\" ConcurrencyMode=\"Fixed\" />"}, 

     { "<Property Name=\"RowVer\" Type=\"Binary\" MaxLength=\"8\" FixedLength=\"true\" annotation:StoreGeneratedPattern=\"Computed\" />", 
      "<Property Name=\"RowVer\" Type=\"Binary\" MaxLength=\"8\" FixedLength=\"true\" annotation:StoreGeneratedPattern=\"Computed\" ConcurrencyMode=\"Fixed\" />"}, 

     { "<Property Name=\"rowver\" Type=\"Binary\" MaxLength=\"8\" FixedLength=\"true\" annotation:StoreGeneratedPattern=\"Computed\" />", 
      "<Property Name=\"rowver\" Type=\"Binary\" MaxLength=\"8\" FixedLength=\"true\" annotation:StoreGeneratedPattern=\"Computed\" ConcurrencyMode=\"Fixed\" />"}, 
    }; 

    static void Main(string[] args) 
    { 
     // find all .edmx 
     string directoryPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); 
     foreach (var file in Directory.GetFiles(directoryPath)) 
     { 
      // only edmx 
      if (!file.EndsWith(".edmx")) 
       continue; 

      Console.WriteLine("File Name Found : " + file); 

      // read file 
      var fileContents = File.ReadAllText(file); 

      // replace lines 
      foreach (var item in replacements) 
       fileContents = fileContents.Replace(item.Key, item.Value); 

      // overwite file 
      File.WriteAllText(file, fileContents); 

      Console.WriteLine("\nFile : " + file + "Changed"); 
     } 
    } 
関連する問題