コンテキストを直接操作するのは良い考えですか?たとえば、顧客のデータベースがあり、ユーザーが名前で顧客を検索し、リストを表示し、リストを選択して、その顧客のプロパティを編集できるとします。
コンテキストを使用して顧客のリスト(POCOまたはにマップされているCustomerViewModels
)を取得し、すぐにコンテキストを閉じる必要があるようです。次に、ユーザーがCustomerViewModels
リストから1つを選択すると、UIの顧客プロパティセクションにデータが入力されます。
次に、名前、タイプ、Webサイトのアドレス、会社の規模などを変更できます。保存ボタンを押すと、新しいコンテキストを開き、からのIDを使用しCustomerViewModel
てその顧客レコードを取得し、各プロパティを更新します。最後にSaveChanges()
、コンテキストを呼び出して閉じます。これはたくさんの仕事です。
私の質問は、コンテキストを直接操作して、コンテキストを開いたままにしないのはなぜですか?ライフタイムスコープが長い同じコンテキストを使用して読んだことがありますが、これは非常に悪いことであり、必然的に問題が発生します。私の想定では、アプリケーションを1人だけが使用する場合は、コンテキストを開いたままにして、すべてを実行できます。ただし、ユーザーが多い場合は、簡潔な作業単位を維持して、リクエストごとにコンテキストを開いたり閉じたりしたいと思います。
助言がありますか?ありがとう。
@PGallagher-徹底的な回答をありがとう。
@Brice-あなたの入力も役に立ちます
ただし、@ManosD.の「冗長コードの縮図」コメントは少し気になります。例を見てみましょう。顧客をデータベースに保存していて、顧客のプロパティの1つがCommunicationMethodであるとします。
[Flags]
public enum CommunicationMethod
{
None = 0,
Print = 1,
Email = 2,
Fax = 4
}
WPFの顧客管理ページのUIには、顧客コミュニケーション方法(印刷、電子メール、ファックス)の下に3つのチェックボックスが含まれます。各チェックボックスをその列挙型にバインドすることはできません。意味がありません。また、ユーザーがその顧客をクリックし、起きて昼食に行くとどうなりますか...コンテキストは何時間もそこにとどまりますが、これは悪いことです。代わりに、これは私の思考プロセスです。
エンドユーザーはリストから顧客を選択します。コンテキストを新しくし、その顧客を見つけてCustomerViewModelを返すと、コンテキストが閉じられます(ここでは簡単にするためにリポジトリを省略しました)。
using(MyContext ctx = new MyContext())
{
CurrentCustomerVM = new CustomerViewModel(ctx.Customers.Find(customerId));
}
これで、ユーザーは、Save()メソッドもあるCustomerViewModelの3つのboolプロパティにバインドされているため、[印刷]、[電子メール]、[ファックス]ボタンをオン/オフにできます。ここに行きます。
public class CustomerViewModel : ViewModelBase
{
Customer _customer;
public CustomerViewModel(Customer customer)
{
_customer = customer;
}
public bool CommunicateViaEmail
{
get { return _customer.CommunicationMethod.HasFlag(CommunicationMethod.Email); }
set
{
if (value == _customer.CommunicationMethod.HasFlag(CommunicationMethod.Email)) return;
if (value)
_customer.CommunicationMethod |= CommunicationMethod.Email;
else
_customer.CommunicationMethod &= ~CommunicationMethod.Email;
}
}
public bool CommunicateViaFax
{
get { return _customer.CommunicationMethod.HasFlag(CommunicationMethod.Fax); }
set
{
if (value == _customer.CommunicationMethod.HasFlag(CommunicationMethod.Fax)) return;
if (value)
_customer.CommunicationMethod |= CommunicationMethod.Fax;
else
_customer.CommunicationMethod &= ~CommunicationMethod.Fax;
}
}
public bool CommunicateViaPrint
{
get { return _customer.CommunicateViaPrint.HasFlag(CommunicationMethod.Print); }
set
{
if (value == _customer.CommunicateViaPrint.HasFlag(CommunicationMethod.Print)) return;
if (value)
_customer.CommunicateViaPrint |= CommunicationMethod.Print;
else
_customer.CommunicateViaPrint &= ~CommunicationMethod.Print;
}
}
public void Save()
{
using (MyContext ctx = new MyContext())
{
var toUpdate = ctx.Customers.Find(_customer.Id);
toUpdate.CommunicateViaEmail = _customer.CommunicateViaEmail;
toUpdate.CommunicateViaFax = _customer.CommunicateViaFax;
toUpdate.CommunicateViaPrint = _customer.CommunicateViaPrint;
ctx.SaveChanges();
}
}
}
これに何か問題がありますか?