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

Cascade addition of entities

2 Answers 69 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.
Alex
Top achievements
Rank 1
Alex asked on 03 Jun 2013, 04:02 PM
I will start directly with the thing I am trying to do - the entities are the following. Document has a collection DocumentDetails and each DocumentDetail has a collection of DocumentDetailProperty entities. As I want trackable collections the code looks like this:

// Document entity
private TrackedBindingList<DocumentDetail> _documentDetails = new TrackedBindingList<DocumentDetail>();
public virtual TrackedBindingList<DocumentDetail> DocumentDetails 

   get
   {
       return this._documentDetails;
   }
}

// DocumentDetail entity
private TrackedBindingList<DocumentDetailProperty> _documentDetailProperties = new TrackedBindingList<DocumentDetailProperty>();
public virtual TrackedBindingList<DocumentDetailProperty> DocumentDetailProperties 

   get
   {
       return this._documentDetailProperties;
   }
} My
scenario is the following: user creates a new DocumentDetail, adds some DocumentDetailProperty entities and saves all changes. The code for both the additions is:

    // adding a DocumentDetail
            DocumentDetail dd = new DocumentDetail() { DocumentId = theDoc.DocumentId };
            theDoc.DocumentDetails.Add(dd);
            context.Add(dd); // is this necessary?

   // adding a DocumentDetailProperty
            DocumentDetailProperty newDDP = new DocumentDetailProperty();
            newDDP.DocumentDetailId = SelectedDocumentDetail.DocumentDetailId; // getting id from selected item. Should handle differently when selected item is just added? It makes no difference when this line is commented 
            SelectedDocumentDetail.DocumentDetailProperties.Add(newDDP);
            context.Add(newDDP);

Save is performed by this code:

                context.FlushChanges();
// just for testing - shold not matter in this scenario
                context.ExecuteQuery<object>("uspAfterSaveTest", CommandType.StoredProcedure,
                    new OAParameter[] { new OAParameter("SomeString", "after save") });
                context.SaveChanges();

the profiler giving the following:

declare @p1 int
set @p1=NULL
exec sp_prepexec @p1 output,N'@p0 int,@p1 int,@p2 varchar(128)',N'declare @generated_ids table([DocumentDetailPropertyId] int)
insert [DocumentDetailProperty] ([DocumentDetailId], [PropertyId], [PropertyValue]) 
output inserted.[DocumentDetailPropertyId] into @generated_ids 
 VALUES (@p0, @p1, @p2) 
select t.[DocumentDetailPropertyId] 
from @generated_ids as g join [DocumentDetailProperty] as t on g.[DocumentDetailPropertyId] = t.[DocumentDetailPropertyId] 
where @@ROWCOUNT > 0',@p0=0,@p1=1,@p2='rewrwer'
select @p1

So, it tries to add only the DocumentDetailProperty entity and it fails as it tries to insert with a DocumentDetailId = 0. How can I perform both the additions with one save? Beside using TrackableCollections, I have mapping type = Xml (this was necessary in order to make TrackableCollection work, as indicated by Telerik in another thread).

Thank you,

Alex D.


2 Answers, 1 is accepted

Sort by
0
Accepted
Yordan
Telerik team
answered on 05 Jun 2013, 02:52 PM
Hello Alex,

Thank you for the detailed code. The reason why you observed such behavior is because of the way how collection properties are managed. In the example code the property IsManaged of the navigation property DocumentDetailProperties is false. It should be set to true and then the child elements DocumentDetails should be added in the following way to the parent document:

using (EntitiesModel dbContext = new EntitiesModel())
{
    Document doc = new Document() { Name = "NameOfDoc" };
    dbContext.Add(doc);
    doc.DocumentDetails.Add(new DocumentDetail() { Name = "DocDetail1" });
    doc.DocumentDetails.Add(new DocumentDetail() { Name = "DocDetail2" });
    dbContext.SaveChanges();
}

This way two DocumentDetails entities will be added to the database and their DocumentId field will be set to the id of the inserted document automatically.
More about managing navigational properties in OpenAccess ORM can be found in this article.

Please find the attached project as an example.

In case you encounter any more difficulties do not hesitate to get back to us.
 
Regards,
Yordan
Telerik
OpenAccess Samples Kit boasts 50+ sample applications providing diverse real-life business solutions. Click to read more and see OpenAccess ORM in action.
0
Alex
Top achievements
Rank 1
answered on 06 Jun 2013, 03:11 PM
It works very well. I have also found that setting Is Dependent = True will allow cascade delete. 

Thanks.
Tags
Data Access Free Edition
Asked by
Alex
Top achievements
Rank 1
Answers by
Yordan
Telerik team
Alex
Top achievements
Rank 1
Share this question
or