none
POCO proxy not able to automatically set up a relationship RRS feed

  • Question

  • hi

    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



    • Edited by KlemS100 Wednesday, October 26, 2011 7:14 PM
    Wednesday, October 26, 2011 7:12 PM

All replies

  • Hi KlemS100,

    I'm not sure why this code works for you:

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

    We couldn't covert Icollection type "value" to List type. Please change it to :

    get { return _addresses; }
    set { _addresses = (List<Address>)value;}
    

    Base on my testing, it works in both scenario, you should let Context to track the "someEmployee" instance first

    context.Employees.Add(someEmployee);

    someEmployee.Addresses.Add(address);

    Have a nice day.

     


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, October 31, 2011 7:16 AM
    Moderator
  • We couldn't covert Icollection type "value" to List type. Please change it to :

    get { return _addresses; }
    set { _addresses = (List<Address>)value;}
    
    This is puzzling. With me it's just the other way around. Namely, my code compiles just fine while your code throws

    'System.InvalidCastException: Unable to cast object of type 'System.Data.Objects.DataClasses.EntityCollection`1[ExampleModel.Address]' to type
    'System.Collections.Generic.List`1[ExampleModel.Address]'


    Base on my testing, it works in both scenario, you should let Context to track the "someEmployee" instance first

    But someEmployee is already tracked automatically by context, so there's no need to explicitly add it to the context. Here is the complete code ( in my initial post i've omitted the code that retrieves someEmployee and address entities  ): 


    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(); }
            }
    }
    
    Employee someEmployee = (from e in context.Employees where e.employeeID == 100 select e).First();
    Address address = (from a in context.Addresses where a.addressID == 1 select a).First(); 
    
    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
    


    I don't understand how it's possible that automatic relationship fix-up works in your code, but not in mine?! 



    • Edited by KlemS100 Monday, October 31, 2011 7:32 PM
    Monday, October 31, 2011 7:27 PM