POCO-прокси не может автоматически устанавливать отношения - PullRequest
0 голосов
/ 26 октября 2011

Одним из требований для прокси-серверов отслеживания изменений является то, что свойство навигации, представляющее конец «многие» отношения, должно возвращать тип, реализующий ICollection.

Прокси отслеживания изменений также предоставляют классы с автоматическим исправлением взаимосвязей . Например, при выполнении someEmployee.Addresses.Add(address); прокси автоматически устанавливает address.EmployeeID в значение 100, а также присваивает someEmployee экземпляр свойству навигации address.Employee:

    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, то по какой-то причине прокси не сможет автоматически исправить отношения:

    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

Свойство навигации Employee.Addresses возвращает тип, который реализует ICollection (List<T>), так почему же прокси не может исправить отношения?

Спасибо

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; }
        }
    }

Ответы [ 2 ]

1 голос
/ 26 октября 2011

Это потому, что сам прокси не фиксирует отношения.Он заменяет ваши созданные экземпляры собственными, но как только вы вызываете 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 голосов
/ 28 марта 2012

Вы также можете попробовать это:

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 также будет автоматически создаваться при создании объекта с помощью new (вместо использования методов CreateObject или Create ) для использования в ситуациях, когда прокси нежелательны (например, сериализация).

Другое изменение заключается в том, что ICollection реализован в виде HashSet <> вместо List <>, обеспечивая уникальность.

...