Search code examples
entity-framework-4entity-relationship

POCO proxy not able to automatically set a relationship


One of the requieremets for change tracking proxies is that a navigation property that represents the "many" end of a relationship must return a type that implements ICollection.

Change tracking proxies also provide classes with automatic relationship fix-up. For example, when someEmployee.Addresses.Add(address); is executed, proxy automatically sets address.EmployeeID to value of 100 and also assigns someEmployee instance to a navigation property 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

But if we change the definition of Employee class, then for some reason proxy isn't able to automatically fix-up the relationship:

    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

Navigation property Employee.Addresses does return a type that implements ICollection ( List<T> ), so why isn't proxy able to fix-up the relationship?

Thank you

EDIT

It is because the proxy itself doesn't fixup the relation. It replaces your instantiated collections with its own but once you call value.ToList() you are throwing away its implementation with fixup logic.

But if calling value.ToList() is the reason why automatic relationship fix-up doesn't work, then removing the setter method should enable automatic relationship fix-up, but it doesn't:

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

        public virtual int EmployeeID { get; set; }

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

Solution

  • It is because the proxy itself doesn't fixup the relation. It replaces your instantiated collections with its own but once you call value.ToList() you are throwing away its implementation with fixup logic. Use this instead and it should work as expected:

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