2

現在の状況では、多くの人が毎日同時に変更を加える必要があるデータバインドされたデータグリッドビューがあります。グリッドは保存および更新できる必要がありますが、非常にアクティブであるため、正しく機能していません。

シナリオは次のとおりです。

  1. 3人が同時にグリッドフォームを開きます。
  2. 3つの異なる行のデータに変更を加えます。
  3. 個人1は変更を保存し、成功します。
  4. Person 2は変更を保存して成功しますが、Person 2のグリッドが、Person 1が送信したばかりのデータと同期されていないため、Person1の変更はなくなりました。
  5. 人物3は変更を保存し、人物3のデータグリッドビューが更新されたデータと同期されなかったため、人物1と2が行ったことをすべて消去します。

私は最初にこのアプローチを試しました:

    private MySqlDataAdapter da;
    private MySqlConnection conn;
    BindingSource bs = new BindingSource();
    DataSet ds = null;
    string qry;
    string ConnString = System.Configuration.ConfigurationManager.AppSettings["ConnectionString"];

    // THE LOAD METHOD
    private void LoadDataToGrid(string srcTable, string query)
    {
        conn = new MySqlConnection(ConnString);
        // ADD ANY QUERY
        qry = query;
        da = new MySqlDataAdapter(qry, conn);
        conn.Open();
        ds = new DataSet();
        MySqlCommandBuilder cb = new MySqlCommandBuilder(da);

        // USE TABLE NAME
        da.Fill(ds, srcTable);
        //USE TABLE NAME
        bs.DataSource = ds.Tables[srcTable];
        dataGridView1.DataSource = bs;

        // CUSTOMIZE GRID
        txtRows.Text = dataGridView1.Rows.Count.ToString();
        dataGridView1.AutoResizeColumns();
        dataGridView1.AllowUserToDeleteRows = false;
    }

    // THE SAVE METHOD
    private void SaveDataFromGrid(string srcTable)
    {
        // USE TABLE NAME
        DataTable dt = ds.Tables[srcTable];
        this.dataGridView1.BindingContext[dt].EndCurrentEdit();
        this.da.Update(dt);

        txtRows.Text = dataGridView1.Rows.Count.ToString();
    }

上記の理由により、これはうまくいきませんでした。データが正しく保存されていませんでした。

これが私の2番目の考えでしたが、それでも上記の問題に悩まされています。

   // Load event
   dataGridView1.DataSource = context.TableName;

   // btnSave_click Event
   connection.open();

       // loop through cells in current row and apply changes by id

   context.tableName.Attach(DataFromGrid);
   context.ObjectStateManager.ChangeObjectState(DataFromGrid, System.Data.EntityState.Modified);
   context.savechanges();

基本的に、この切断の問題をどのように解決できますか?誰かが以前にこの問題を抱えたことはありますか?

4

1 に答える 1

0

この問題は、1つのコードスニペットで解決するよりもおそらく複雑です。実装に入る前に、最初に解決すべきことがいくつかあるようです。

まず、各人の変更は実際にグリッド全体をコミットする必要がありますか?シナリオに応じて、各人が異なる行のデータを変更します。変更された行のみに変更をコミットするようにコードを変更すると、競合シナリオが大幅に削減されます。

次に、競合が1行で発生しているか多数で発生しているかに関係なく、競合の管理方法を決定する必要があります(たとえば、データベースの勝ち、ユーザーの選択など)。

EFは楽観的同時実行モード(データベースロックなし)を実装しますが、デフォルトでは、ローカル変更をコミットするときにデータベース変更を上書きすることを選択します。EF構成を変更して、ConcurrenyMode = Fixedを設定する必要があります。これにより、行をコミットする前に「最新の状態になっていない」場合に変更が自動的に上書きされないようになります。

EFが同時実行を処理する方法の詳細については、http://msdn.microsoft.com/en-us/library/bb738618.aspxを参照してください。

EF構成を変更すると、競合が検出されたときに例外が発生し始めます。これは、データベース内のデータを更新する(ローカルの変更を使用)か、ローカルデータを更新する(データベースの変更を使用)ことにより、処理する必要があります。 )。

于 2012-05-24T22:40:09.893 に答える