This is a migrated thread and some comments may be shown as answers.

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

3 Answers 62 Views
Data Access Free Edition
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Gary
Top achievements
Rank 1
Gary asked on 19 Aug 2015, 05:17 PM
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.}

3 Answers, 1 is accepted

Sort by
0
Boris Georgiev
Telerik team
answered on 24 Aug 2015, 11:08 AM
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.
0
Gary
Top achievements
Rank 1
answered on 24 Aug 2015, 02:51 PM

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. 

0
Accepted
Pavel Uzunov
Telerik team
answered on 27 Aug 2015, 09:06 AM
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.
Tags
Data Access Free Edition
Asked by
Gary
Top achievements
Rank 1
Answers by
Boris Georgiev
Telerik team
Gary
Top achievements
Rank 1
Pavel Uzunov
Telerik team
Share this question
or