1

こんにちは、

私は現在、winformsアプリケーション内でEntity Framework DbContext /CodeFirstを操作しようとしています。私のクラスPrintQueueItemは、 「Pending」に等しいPrintStatusを持つPrintQueueItemのみを返すデータベース内のビューにマップされます。これは、DataGridViewを介してエンドユーザーに表示されるため、エンドユーザーは1日の終わりにバッチ印刷される内容を表示できます。ユーザーはPrintQueueItemのインスタンスを追加でき、これはDataGridView内にも表示されます。

印刷するように設定されているアイテムをキャンセルしようとすると、問題が発生します。PrintStatusCanceledに設定してから、ExecuteSqlCommandを実行してデータベースを更新します。この後、情報をリロードしようとしましたが、アイテムはまだDataGridView内に表示されています。情報が再度ロードされた後、(ローカル経由で)カウントを取得したときに、これが1つ減った理由がわかりません。BindingListがデータバインディングの双方向同期を提供し、UIがデータの変更に応じて更新されると思ったので、これがなぜであるかについて何か考えはありますか?

PrintQueueItem(モデル)

public class PrintQueueItem
{
    public PrintQueueItem()
    {
        this.PrintQueueID = Guid.NewGuid();
        this.PrintStatus = "Pending";
        this.DateAdded = DateTime.Now;
    }

    public Guid PrintQueueID { get; set; }
    public Guid DocumentID { get; set; }
    public string PrintStatus { get; set; }
    public DateTime DateAdded { get; set; }

    public virtual Documentation Document { get; set; }
}

初期バインディング

this.printQueueBinding.DataSource = db.PrintQueue.Local.ToBindingList();
this.printQueueGridView.AutoGenerateColumns = false;
this.printQueueGridView.DataSource = printQueueBinding;

PrintQueueItemのPrintStatusを更新し、リロードします

PrintQueueItem item = printQueueBinding.Current as PrintQueueItem;
if (item == null)
{
    throw new ArgumentNullException("Could not obtain instance of selected 'PrintQueueItem'");
}
item.PrintStatus = "Cancelled";
this.db.Database.ExecuteSqlCommand("exec usp_PrintQueue_Update {0}, {1}",item.PrintQueueID, item.PrintStatus);
this.db.PrintQueue.Load();

いくつかの追加の注意事項

ExecuteSqlCommandを呼び出す代わりに、SaveChangesを呼び出そうとしましたが、次のような例外が発生しました。

"Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded." 

これは、アイテムが更新されたときにビューにアイテムが見つからなくなったためだと思います。そうでない場合はお知らせください。

アプリケーションでフィルタリングではなくフィルタリングされたビューを使用する理由は、BindingListがIBindingListViewを実装しておらず、DataGridView内に表示されるデータをフィルタリングするためのBindingList.Filterメソッドを実装できないためです。これに関する提案も歓迎します。

ご協力ありがとうございました。

4

1 に答える 1

0

ビールを数杯飲んだ後、しばらくして、頭の中で混乱していた論理の混乱を今日の初めから片付けました。私は実際に何が起こっているのかを考え始めましたが、SaveChangesを呼び出そうとすると、同時実行例外が発生していることに気付きました。

発生した例外の種類に注意を払うことができなかったため、適切に処理できませんでした。その後、コードを次のように更新したため、DbUpdateConcurrencyExceptionが発生すると(ビューにレコードが含まれなくなったため、予想されます)、問題が発生したエンティティがデータベースから更新されます。

        try
        {
            if (Program.YesNoQuestion(string.Format("Cancel print job for the selected document?", printQueueGridView.SelectedRows.Count)) != System.Windows.Forms.DialogResult.Yes)
            {
                return;
            }

            PrintQueueItem item = printQueueBinding.Current as PrintQueueItem;
            if (item == null)
            {
                throw new ArgumentNullException("Could not obtain an instance of 'PrintQueueItem'");
            }

            item.PrintStatus = "Cancelled";
            this.db.Database.ExecuteSqlCommand("exec usp_PrintQueue_Update {0}, {1}", item.PrintQueueID,
                                                                                           item.PrintStatus);
            //this.db.PrintQueue.Load();
            this.db.SaveChanges();
        }
        catch (DbUpdateConcurrencyException ex)
        {
            foreach (DbEntityEntry entry in ex.Entries)
            {
                entry.Reload();
            }
        }

私は常に他のアイデアを受け入れており、常に適切な方法で物事を行うことに興味を持っているので、これについてもっと良い方法があるかどうか教えてください。おやすみ!

于 2012-12-20T02:33:12.140 に答える