2011-10-26 11 views
0

変更追跡プロキシの要件の1つは、リレーションシップの「多くの」末尾を表すナビゲーションプロパティが、ICollectionを実装するタイプを返す必要があることです。POCOプロキシが自動的にリレーションシップを設定できない

また、変更追跡プロキシは、の自動関係の修復のクラスも提供します。例えば、someEmployee.Addresses.Add(address);が実行された場合、プロキシは自動的に100の値にaddress.EmployeeIDを設定し、また、ナビゲーションプロパティaddress.EmployeesomeEmployeeインスタンスを割り当てます。

public class Employee 
    { 
     public virtual int EmployeeID { get; set; } 

     public virtual ICollection<Address> Addresses { get; set; } 
    } 

Employee someEmployee = ...; 
Address address = ...; 

Console.WriteLine(someEmployee.EmployeeID); // 100 
Console.WriteLine(address.EmployeeID); // 20 

someEmployee.Addresses.Add(address); 

Console.WriteLine(address.EmployeeID); // 100 
Console.WriteLine(address.Employee.EmployeeID); // 100 

しかし、我々はその後、Employeeクラスの定義を変更した場合何らかの理由でプロキシISNのために自動的に修正アップする関係をできる「T:ICollectionを実装タイプ(List<T>)を返しませんので、なぜ修正アップするトンをでき代理ではありませんEmployee.Addresses

public class Employee 
    { 
     private List<Address> _addresses = new List<Address>(); 

     public virtual int EmployeeID { get; set; } 

     public virtual ICollection<Address> Addresses 
     { 
      get { return _addresses; } 
      set { _addresses = value.ToList(); } 
     } 
    } 

Console.WriteLine(someEmployee.EmployeeID); // 100 
Console.WriteLine(address.EmployeeID); // 20 

someEmployee.Addresses.Add(address); 

Console.WriteLine(address.EmployeeID); // 20 
Console.WriteLine(address.Employee.EmployeeID); // 20 

ナビゲーションプロパティ彼の関係?

は、プロキシ自体が関係に修復していないので、それはあなたに

EDIT

をありがとうございました。インスタンス化されたコレクションを独自のものに置き換えますが、一旦value.ToList()を呼び出すと、フィックスアップロジックでその実装を捨ててしまいます。

しかしvalue.ToList()を呼び出すと、自動関係フィックスアップが自動関係フィックスアップを有効にする必要があり、その後setter除去方法、動作しない理由は、それがない場合:

public class Employee 
    { 
     private List<Address> _addresses = new List<Address>(); 

     public virtual int EmployeeID { get; set; } 

     public virtual ICollection<Address> Addresses 
     { 
      get { return _addresses; } 
     } 
    } 

答えて

1

それプロキシ自体が関係をフィックスアップしないからです。インスタンシエイトされたコレクションを独自のものに置き換えますが、value.ToList()に電話すると、フィックスアップロジックでその実装を捨ててしまいます。これは、代わりに使用すると、期待どおりに動作するはずです:また、この試すことができ

public class Employee 
{ 
    public ICollection<Address> addresses = new List<Address>(); 

    public virtual int EmployeeId { get; set; } 

    public virtual ICollection<Address> Addresses 
    { 
     get { return addresses; } 
     set { addresses = value; } 
    } 
} 
+0

まだ動作しません – user702769

+1

作業用のソリューションからコピーしました –

+0

あなたは正しいです。あなたの提案がうまくいかなかった理由は、プロパティの1つが仮想とマークされていないためです。とにかく、自動リレーションシップフィックスアップが機能しない理由は、value.List()を呼び出すことによるものなのでしょうか? – user702769

0

public class Employee { 
    private ICollection<Address> _addresses = new HashSet<Address>(); 

    public virtual int EmployeeID { get; set; } 

    public virtual ICollection<Address> Addresses { 
     get { return _addresses ?? (_addresses = new HashSet<Address>()); } 
     protected set { _addresses = value; } 
    } 
} 

を利点は、あなたを作成するときにPOCOクラス内のアドレスのコレクションも自動的にインスタンス化されるということですプロキシが望ましくない状況(例:シリアライゼーション)で使用するためにnewCreateObjectまたはCreateのメソッドを使用するのではなく)のエンティティ。

ICollectionがリスト<>の代わりにHashSet <>として実装され、一意性が保証されます。

関連する問題