locked
Using dynamic proxy POCOs RRS feed

  • Question

  •  

    I posted this question on stack overflow but didnt get an answer so was reposting it here. As an example I have a database with two tables , company and employee with a one to many relationship. I am using EF 4. I was going through Julie Lerman's book and the firestarter sessions on channel 9 and have some questions on using dynamic proxies

    1.  It is mentioned that when using dynamic proxies, creation of new objects should be done through ObjectContext.CreateObject and not by saying new Object() (for reference 1:09 in the video mentioned above). She clearly says that if you try adding an object in this manner it wont get added to the database and I won't even get an error. However I tried the following and it worked

    try
        {
            using (
    var context = new sandeepTestEntities1())
            {
               
    var company1 = (from c1 in context.Companies
                                where c1.
    Name == "xyz"
                               
    select c1).Single();

               
    Employee e = new Employee();
                e.
    CompanyId = company1.Id;
                e.
    Age = 25;
                           e.Name = “James”;

     context.Employees.AddObject(e);


                context.
    SaveChanges();
            }
        }
       
    catch (Exception ex)
        {
           
    MessageBox.Show(ex.ToString());
        }

    I am unable to understand the use of the CreateObject method in this scenario. I felt that it might have something to do with relationship and foreign key fixup but even that works when using the code above.

    2.  It is also mentioned that if we have any custom code in the setters for the entities and we are using dynamic proxies the code doesnt get called. (1:14 in the video). In my example for the Employee entity I have the following code for the name property

    public virtual string Name
    {
           get{
    return _name;}
            set
                {
                   
    if (value != null && value.Length > 50)
                     {
    throw new ArgumentException("Name must be less than 50 characters");}
               
    else
                { _name = value;}
                }

        }

     

    I chnaged the code above for creating an employee to

    try
            {
                using (
    var context = new sandeepTestEntities1())
                {
                   
    var company1 = (from c1 in context.Companies
                                    where c1.
    Name == "xyz"
                                   
    select c1).Single();
                   
    var e = context.CreateObject<Employee>();
                    e.
    CompanyId = company1.Id;
                    e.
    Age = 25;
                    e.
    Name = "X".PadLeft(51,'.');
                    context.
    Employees.AddObject(e);
                    context.
    SaveChanges();
                }
            }
           
    catch (Exception ex)
            {
               
    MessageBox.Show(ex.ToString());
            }

    and I still get an exception when assigning the Name indicating that my custom code is being called. Is my understanding of both these points incorrect ?

     

    Monday, January 23, 2012 5:59 PM

Answers

  • Hi paladugu457,

    Sorry for late reply, I have just ended my holiday.

    Based on the question. First, Call AddObject will add the object to the object context. Do this when the object is a new object that does not yet exist in the data source. So you can see the object has been added into the object state manager's addedEntityStore. The second question, if you using dynamic proxies, entity framework will generate a derived class which derive from the POCO class you defined, the purpose is to enable lazy loading or fix-up two way relationships. I don't know why you said the setter will not work, you can add a breakpoint at SaveChanges method and debug. You will see a type named as the actual POCO class type name with a hash followed, it is the proxy class which Entity Framework generated, please look at the setter section of that class.

    Best Regards


    Allen Li [MSFT]
    MSDN Community Support | Feedback to us
    • Marked as answer by Allen_MSDN Monday, February 6, 2012 2:03 AM
    Friday, February 3, 2012 8:31 AM

All replies

  • Hi paladugu457,

    Welcome to MSDN Forum.

    The CreateObject(Of T) method is used with POCO custom data classes to make sure that the returned object can be managed correctly by the Entity Framework. If you use a new keyword to instantiate a instance and want the statemanager to trace its changes, you have attach it to the context. But if you use CreateObject to create an instance, it can be traced by context.

    About the second question, I have not seen the video and I don't have the book you mentioned. If you use POCO proxies, Entity Framework will autogenerate a Type inherited from your POCO class and override the virutual property, so the customized in the setters makes no sense. I think this is her meaning.

    Here are some links I think can help you to learn it.

    http://msdn.microsoft.com/en-us/library/dd487204.aspx

    http://msdn.microsoft.com/en-us/library/dd468057.aspx

    http://blogs.msdn.com/b/adonet/archive/2009/12/22/poco-proxies-part-1.aspx

    Best Regards


    Allen Li [MSFT]
    MSDN Community Support | Feedback to us
    Wednesday, January 25, 2012 3:01 AM
  • Allen, Theoretically from what you have said and what I have read, I understand why the two statements make sense. My question however was if the two statements are supposed to be correct how come they don't work in the examples above.  

    1. Why am i able to use new Object() and create a pure POCO object and still have it added to the database when save changes is called? Even before save changes is called and after AddObject() i can see the object being added to the object state manager's addedEntityStore. I was assuming that the pure POCO object was beng added becaus ethe saveChanges inherintly calls DetectChanges() but that doesnt seem to be the case.

    2. Why does my customized setter code still get called when I am using dynamic proxies (when according to the statement it shouldn't be)

    Wednesday, January 25, 2012 5:21 PM
  • Hi paladugu457,

    Sorry for late reply, I have just ended my holiday.

    Based on the question. First, Call AddObject will add the object to the object context. Do this when the object is a new object that does not yet exist in the data source. So you can see the object has been added into the object state manager's addedEntityStore. The second question, if you using dynamic proxies, entity framework will generate a derived class which derive from the POCO class you defined, the purpose is to enable lazy loading or fix-up two way relationships. I don't know why you said the setter will not work, you can add a breakpoint at SaveChanges method and debug. You will see a type named as the actual POCO class type name with a hash followed, it is the proxy class which Entity Framework generated, please look at the setter section of that class.

    Best Regards


    Allen Li [MSFT]
    MSDN Community Support | Feedback to us
    • Marked as answer by Allen_MSDN Monday, February 6, 2012 2:03 AM
    Friday, February 3, 2012 8:31 AM