Navigation Properties are being Populated When Add() ing New Entity

4 posts, 1 answers
  1. Gary
    Gary avatar
    28 posts
    Member since:
    Jun 2015

    Posted 19 Aug 2015 Link to this post

    I am running into an issue where when I add an entity to a Telerik DbContext, the navigation properties are being automatically populated which is causing problems downstream.

    For example, I have a DeliverableEntity class that looks like (not the ENTIRE class code, but hopefully the relevant pieces)...


    01.public partial class DeliverableEntity {       
    02. 
    03.    [System.ComponentModel.DataAnnotations.Required()]
    04.    [System.ComponentModel.DataAnnotations.Key()]
    05.    public virtual long ID { ... }
    06. 
    07.    [Collection(InverseProperty = "Deliverable", IsManaged = true)]
    08.    public virtual IList<DeliverableAttributeEntity> Attributes { ... }
    09.}


    And each of the DeliverableAttributeEntity classes look like ... 


    01.public partial class DeliverableAttributeEntity {
    02.    [System.ComponentModel.DataAnnotations.Required()]
    03.    [System.ComponentModel.DataAnnotations.Key()]
    04.    public virtual long ID { ... }
    05. 
    06.    public virtual long DeliverableId { ... }
    07.     
    08.    public virtual DeliverableEntity Deliverable { ... }
    09.}


    They each contain a reference to each other. The problem comes when I attempt to Add a new DeliverableAttributeEntity that has the DeliverableId defined but the Deliverable property is null.

     

    1.AttributeEntity.ID            = 0;    // It does not yet exist in the database
    2.AttributeEntity.DeliverableId = 134;  // Id of an existing Deliverable record
    3.AttributeEntity.Deliverable   = null; // No reference to the existing Deliverable


    When I Add this to the context (I'm using generics to do this) ...

    01.// T = DeliverableAttributeEntity
    02.public virtual T AddEntity(T entity)
    03.{
    04.    this.DbContext.Add(entity); // here it is populating the "Deliverable" Navigation Prop
    05. 
    06.    if (!this.IsPassedInContext) {
    07.        this.DbContext.SaveChanges();
    08.    }
    09. 
    10.     return entity;
    11.}


    Even though the *Deliverable* property of the *entity* argument was null when it when it's passed in, it is being populated in the returned *entity* parameter when the Add() method is called. 


    1.AttributeEntity.ID            = 0;                 // It does not yet exist in the database
    2.AttributeEntity.DeliverableId = 134;               // Id of an existing Deliverable record
    3.AttributeEntity.Deliverable   = DeliverableEntity; // Reference now exists


    Normally I would think of this as a good thing but is leading to some issues downstream. Is there some way to disable this behavior?

    UPDATE:

    I tried removing the "managed" flag from the *Attributes* navigation property on the *DeliverableEntity* ... 


    01.public partial class DeliverableEntity {
    02.     
    03.    [System.ComponentModel.DataAnnotations.Required()]
    04.    [System.ComponentModel.DataAnnotations.Key()]
    05.    public virtual long ID { ... }
    06. 
    07.    [Collection(InverseProperty = "Deliverable")]
    08.    public virtual IList<DeliverableAttributeEntity> Attributes { ... }
    09.}


    This resolved the issue with the Deliverable being added to the Attribute on the Add() method. However it is now being populated when the SaveChanges() is called. 


     
    01.// T = DeliverableAttributeEntity
    02.public virtual T AddEntity(T entity) {
    03. 
    04.    this.DbContext.Add(entity); // Not populating DeliverableEntity here anymore
    05. 
    06.    if (!this.IsPassedInContext)
    07.    {
    08.        this.DbContext.SaveChanges(); // populating DeliverableEntity here now
    09.    }
    10. 
    11.    return entity;
    12.}
  2. Boris Georgiev
    Admin
    Boris Georgiev avatar
    190 posts

    Posted 24 Aug 2015 Link to this post

    Hi,

    When the association is managed by the context, the navigation properties are populated automatically by the context when there is a change on one of the ends of the association. This is why when you change the association to not be managed by the context, the navigation property is populated when a transaction is committed - SaveChanges() method is called.

    The purpose of the Navigation property is to contain a quick reference to all entities of one type that are linked to the entity which contain the navigation property. If you want a different behavior from the navigation property, you should remove the navigation property and implement your own property with a different logic.

    I hope that helps.

    Regards,
    Boris Georgiev
    Telerik
     
    Check out the latest announcement about Telerik Data Access vNext as a powerful framework able to solve core development problems.
  3. DevCraft banner
  4. Gary
    Gary avatar
    28 posts
    Member since:
    Jun 2015

    Posted 24 Aug 2015 in reply to Boris Georgiev Link to this post

    Thank you for the explanation. I frequently want this behavior but was hoping I could simply turn it off when it was not necessary, or more importantly introduced an issue. It sounds like it's a bit of an all or nothing thing with the navigation properties which is, admittedly a little disappointing. I think I will try, instead of deleting the navigation properties maybe adding a new internally managed property. This will at least leave me with the navigation properties if I want them but certainly does increase the amount of coding and ​design I will have to do. 

     

    Thank you again. 

  5. Answer
    Pavel Uzunov
    Admin
    Pavel Uzunov avatar
    14 posts

    Posted 27 Aug 2015 Link to this post

    Hello Gary,

    Telerik Data Access does not offer a switch for the navigational properties for the time being. 

    In case you are developing kind of web service then it could be an option for you to exclude those properties from serialization/deserialization as described in this article. 

    I hope this information helps.

    Regards,
    Pavel Uzunov
    Telerik
     
    Check out the latest announcement about Telerik Data Access vNext as a powerful framework able to solve core development problems.
Back to Top