1

マルチユーザー環境と今後の Web サイトをより適切にサポートするために、現在使用している winforms アプリケーションから DbContext を分離しようとしています。少し調査を行った後、winforms アプリ/Web サイトが接続するためのデータ アクセス レイヤー (DAL) を実装し、エンドユーザーが切断されたエンティティを操作できるようにしました。私の質問は、子コレクション内のエンティティの 1 つが更新されたときに、エンティティの更新を保存する最善の方法に関するものです。

たとえば、次の構造(簡略化)がある場合

public class Company
{
    public int CompanyID { get; set; }
    public string CompanyName { get; set; }
    public ICollection<Employee> Employees { get; set; }  // Non-virtual as we aren't lazy-loading
}

public class Employee
{
    public int CompanyID { get; set; }
    public int EmployeeID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public ICollection<Claim> Claims { get; set; }
}

public class Claim
{
    public DateTime ClaimDate { get; set; }
    public ICollection Documentation { get; set; }
}

public class Document
{
    public byte[] DocumentImage { get; set; }
    public string Name { get; set; }
    public DateTime CreateDate { get; set; }
}

winforms アプリケーション内には、従業員の情報を表示するための複数のバインディング ソースのセットアップがあります。

例えば:

employeeBinding.DataSource = typeof(Employee);   // Eventually set to an IEnumerable<Employee>
claimBinding.DataSource = employeeBinding;
claimBinding.DataMember = "Claims";
documentationBinding.DataSource = claimBinding;
documentationBinding.DataMember = "Documentation";

ただし、このように設定すると、各バインディング ソースの "CurrentChanged" イベントを呼び出して、各エンティティが変更されたため保存できません (フォーム内の前のエンティティへの参照が保存されている場合を除く)。したがって、私が考えたのは、DAL で以下に似たものであり、各子コレクションを反復処理することでした。

public void UpdateEmployee(Employee employee) 
{
   using (myContext context = new myContext())
   {
     context.Employees.Attach(employee);
     context.Entry<Employee>(employee).State = EntityState.Modified;

     foreach(var claim in employee.Claims) 
     {
       context.Entry<Claim>(claim).State = EntityState.Modified;
       foreach(var doc in claim.Documentation)
       {
         context.Entry<Document>(doc).State = EntityState.Modified;
       }
     }
     context.SaveChanges(); 
   }
}

ただし、このルートは、いくつかのより複雑なエンティティーと関係を使用すると、すぐに醜くなる可能性があると感じています。誰かがこれを処理するための最良のルートを教えてくれますか、それともコード内の現在のエンティティへの参照を持っている必要がありますか?

どうもありがとうございました。

4

2 に答える 2

0

私は間違っているかもしれませんが、切断されたエンティティに変更が加えられたことを DetectChanges が判断できるとは思えません。エンティティがアタッチされると、EntityState は "Unchanged" になるため、状態を "Modified" としてマークするまで DbContext は何もしません。また、次の URL に示されているように、「DetectChanges」は多くのメソッド (「Attach」を含む) に対して呼び出され、明示的な呼び出しは必要ありません。

http://msdn.microsoft.com/en-us/data/jj556205.aspx

BindingSource に関しては、実際にデータを取得し、そのデータソースをダルコール。これを行わないと、「DataMember」プロパティにバインドしようとしたときに、他の BindingSources が指定されたプロパティを見つけることができないため、問題が発生します。

あなたがサンプルとして提供したコードが、子コレクションの更新に関して私が遭遇した問題を解決するとは思わない。LinqPad でテストすると、親エンティティも変更された場合は更新されますが、親に変更がまったくない場合は更新されません。そのため、すべての子コレクションを繰り返し処理し、それらを「変更済み」としてマークしていました。

于 2013-08-23T12:16:04.710 に答える