Deleting last child entity and adding new in PK-FK relations.

Posts   
 
    
Posts: 7
Joined: 27-Jan-2017
# Posted on: 27-Jan-2017 15:53:09   

Hi all,

I've a query regarding the entity relations I have set for PK FK. I have a Company entity (parent) with a CompanyManagement (child) entity. The PK of parent table is a nullable FK in the child (i.e. ID). Both entities can exist independently. They have 1-M relation where a Company entity has an entity collection of CompanyManagement entities.

I've an issue with deleting the last child entity from parent entity. In my case lets say the parent entity has 2 child entities its referencing. I'm getting the parent entity with prefetch on child entities collection. In order to delete, I set the FK ID in child to null (i.e. child entity sets parent ID to null, not the parent object), which in turn generates a correct UPDATE statement to set the FK in child to NULL if I keep atleast 1 child entity in parent.

I'm sending the parent entity to save.

But lets say I delete the last existing child entity (by setting its parent ID to null), add another new CompanyManagement child entity and I send the parent entity to save it does not generate the Update statement to make the parent ID null in child entity. It does generate the Update statement to set the new relation though.

Are we missing some setup at entity or collection level to generate the correct Update statement.

Please Note, this works correct if I keep atleast 1 child entity before saving parent entity.

Hope I'm able to explain this correct and someone is able to help me out with this.

Thanks in advance.

Best Regards, Kapil

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 28-Jan-2017 12:27:05   

Hi Kapil,

In order to help your better, please provide more info (the code you have so far and details about your LLBLGen version and setup). Ref: http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=7717

David Elizondo | LLBLGen Support Team
Posts: 7
Joined: 27-Jan-2017
# Posted on: 30-Jan-2017 14:42:26   

daelmo wrote:

Hi Kapil,

In order to help your better, please provide more info (the code you have so far and details about your LLBLGen version and setup). Ref: http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=7717

Hi daelmo,

Sorry for not providing further details. I thought it was enough.

We are using LLBLGen 5.1 version.

below is the code that can hopefully get some solution:

    //Start : Code that gets the entity with children using prefetch
            //CompanyEntity has an entity Collection of Management entity
            //public virtual EntityCollection<ManagementDetailEntity> ManagementDetail
    _var includeFieldsForAccComp = new EntityField2[] {
    CompanyFields.CoyId,--PK
            CompanyFields.CmpName,
            CompanyFields.CoyFinYearStart,
            CompanyFields.CoyFinYearEnd
        };

        var includeFieldsForMgmtDet = new IncludeFieldsList(new EntityField2[] {
            CompanyManagementDetailFields.VmdId,--PK
            VesselManagementDetailFields.VmdManageStart,
            VesselManagementDetailFields.VmdManageEnd,
            VesselManagementDetailFields.VmdAlternativeCode,
            VesselManagementDetailFields.CoyId--FK
        });

        var prefetchPathFromAccCompany = new PrefetchPath2(EntityType.CompanyEntity);
        var pathManagementDetails = prefetchPathFromAccCompany.Add(CompanyEntity.PrefetchPathManagementDetail, includeFieldsForMgmtDet);

        var qf = new QueryFactory();

        var query = qf.Company.Where(CompanyFields.CoyId == 'ABC')
            .Include(includeFieldsForAccComp)
            .WithPath(pathManagementDetails);

        var response = new CompanyEntity();

        using (DataAccessAdapter adapter = ServiceHelper.ServiceAdapter)
        {
            response = adapter.FetchFirst(query);
        }

        return response;_
    //End : Code that gets the entity with children using prefetch

    //Start : Code that removes the relation 
    _companyEntity.ManagementDetail[n].CoyId = null;_
    //End : Code that removes the relation
            // This line fires the Update on Management entity to set the CoyId as null in DB 
            //Update statement generated correctly when last management child not removed 
            //But when last removed and another added
            //It generates only the added Management entity Update statement, update to set the last one to Null is not generated.


            //Start : Code to save company entity
            _UnitOfWork.AddForSave(company, false);
            using (var adapter = ServiceHelper.ServiceAdapter)
        {
                response.RecordsAffected = UnitOfWork.Commit(adapter);
            }_
            //End : Code to save company entity
daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 31-Jan-2017 06:52:00   
 companyEntity.ManagementDetail[n].CoyId = null;
...
UnitOfWork.AddForSave(company, false);

Above code won't work the update on the removed relation, because the child entity doesn't exist anymore on the parent collection.

Try this to make it work: Separate the child entity and add it for update to your UOW:

 var child = companyEntity.ManagementDetail[n];
child.CoyId = null;
...
UnitOfWork.AddForSave(child, false);
David Elizondo | LLBLGen Support Team
Posts: 7
Joined: 27-Jan-2017
# Posted on: 01-Feb-2017 07:28:08   

daelmo wrote:

 companyEntity.ManagementDetail[n].CoyId = null;
...
UnitOfWork.AddForSave(company, false);

Above code won't work the update on the removed relation, because the child entity doesn't exist anymore on the parent collection.

Try this to make it work: Separate the child entity and add it for update to your UOW:

 var child = companyEntity.ManagementDetail[n];
child.CoyId = null;
...
UnitOfWork.AddForSave(child, false);

Thank you daelmo,

But im still not getting it. It does fire the Update to make FK null if lets say I have 2 child managements and i remove the relation for only one of the child managements.

I think its an issue only when i remove all management child relations. Thats when the Update to make null is not fired.

Does LLBL Gen keep a track of this internally somehow or is there any step that im missing maybe !?

Thanks again ...

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 01-Feb-2017 19:09:45   

Which runtime library version (build no.) are you using?

Did you try David's suggestion?

Posts: 7
Joined: 27-Jan-2017
# Posted on: 02-Feb-2017 12:13:37   

Walaa wrote:

Which runtime library version (build no.) are you using?

Did you try David's suggestion?

My runtime version is v4.0.30319

Sorry, I havent tried Davids suggestion yet since I do not get the managements as a child of the parent company entity.

I will have to pass them separately as a parameter which is something we need to avoid due to major code changes.

But it does work if I keep atleast one child in the parent company!

Thanks.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 02-Feb-2017 17:29:47   

That's the .NET Framework version number.

Please check the following guidelines thread, to know how to get the LLBLGen RTL version number. http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=7717

Posts: 7
Joined: 27-Jan-2017
# Posted on: 03-Feb-2017 10:51:49   

Walaa wrote:

That's the .NET Framework version number.

Please check the following guidelines thread, to know how to get the LLBLGen RTL version number. http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=7717

My LLBLGen Pro version is v5.1.2.0

For the below point :

_The runtime library version is obtainable by rightclicking the SD.LLBLGen.Pro.ORMSupportClasses.NETxy.dll in windows explorer and then by selecting properties and the version tab. The version is then enlisted at the top as the fileversion. It has the typical format as 2.0.0.YYMMDD, or starting in 2007, the format v.0.YY.MMDD, where 'v' is the version number, e.g. '3'. _

I'm not getting the above file exactly as it is. Im using SD.LLBLGen.Pro.ORMSupportClasses.dll Also in windows explorer im not getting the version tab on the file properties dialog(Windows 10) I do see Previous versions tab which is empty. So I don't see a version in that format above confused

I'm using LLBLGen with Adapter having .NET runtime version v4.0.30319

Database SQL Server 2012. Provider I'm not sure here I think the default SQL provider.

Above code posted is almost the same as in the application. I've only removed some entities which are not related to this i suppose.

Hope that helps you with finding the issue.

Thanks again.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 06-Feb-2017 23:54:58   

We updated the guideline post with the version number guideline for v5.

I second David.

I couldn't reproduce the issue.

Once you set the FK to null, the related entity is de-referenced from the parent entity, and hence the UnitOfWork saving the parent, will not see these child entities to updates.

This is true, whether it is the last child or not.

So please use David's approach.

Sorry, I havent tried Davids suggestion yet since I do not get the managements as a child of the parent company entity.

I will have to pass them separately as a parameter which is something we need to avoid due to major code changes.

You don't need to do that, you can use the same approach that you used to identify the child entities that needs to be removed. As in David's example, use the indexer "n" that you used in your code to get hold on the child entities, you don't need to receive those entities as parameters to your method.

var managementDetail = companyEntity.ManagementDetail[n];
managementDetail.CoyId = null;
UnitOfWork.AddForSave(managementDetail, false);

Btw, maybe it's a typo, but worth mentioning, just in case, in the UoW, you are using "company", while in the previous lines it was "companyEntity".

companyEntity.ManagementDetail[n].CoyId = null;

            //Start : Code to save company entity
            UnitOfWork.AddForSave(company, false);
Posts: 7
Joined: 27-Jan-2017
# Posted on: 07-Feb-2017 07:56:58   

Thanks Walaa for your inputs.

//Start : Code that removes the relation 
companyEntity.ManagementDetail[n].CoyId = null;
//End : Code that removes the relation

But this code above is inside a WPF method.

//Start : Code to save company entity
UnitOfWork.AddForSave(company, false);
using (var adapter = ServiceHelper.ServiceAdapter)
{
     response.RecordsAffected = UnitOfWork.Commit(adapter);
}
//End : Code to save company entity

This code above is inside a different WCF method which takes the company entity as a parameter. That is what is making the change to add an extra parameter difficult.

Btw, maybe it's a typo, but worth mentioning, just in case, in the UoW, you are using "company", while in the previous lines it was "companyEntity".

So the variable "company" (WCF method parameter) is different than the variable "companyEntity"(WPF method variable)

You don't need to do that, you can use the same approach that you used to identify the child entities that needs to be removed. As in David's example, use the indexer "n" that you used in your code to get hold on the child entities, you don't need to receive those entities as parameters to your method.

var managementDetail = companyEntity.ManagementDetail[n];
managementDetail.CoyId = null;
UnitOfWork.AddForSave(managementDetail, false);

Also that is the reason I cannot use the local variable managementDetail as mentioned in your code above inside my WCF.

Strangely it works by updating the child if atleast one child kept in the parent collection. Please let me know.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 07-Feb-2017 10:10:13   

If you set the child's FK to null, it gets dereferenced from the parent. This means that the entity is no longer in the graph. So when you then save the Company, it won't be reached (it should be removed from the Company's CompanyManagement collection.

To be able to save the change, you have to save the CompanyManagement instance which FK you set to null as well.

I think it 'worked' before because for some reason the entities were kept somewhere in the graph either through the GUI or other relationships between entities. (e.g. a relationship among CompanyManagement ?)

Frans Bouma | Lead developer LLBLGen Pro
Posts: 7
Joined: 27-Jan-2017
# Posted on: 07-Feb-2017 15:51:10   

Otis wrote:

If you set the child's FK to null, it gets dereferenced from the parent. This means that the entity is no longer in the graph. So when you then save the Company, it won't be reached (it should be removed from the Company's CompanyManagement collection.

To be able to save the change, you have to save the CompanyManagement instance which FK you set to null as well.

I think it 'worked' before because for some reason the entities were kept somewhere in the graph either through the GUI or other relationships between entities. (e.g. a relationship among CompanyManagement ?)

Ok Thanks Otis. I will try to find out if anything like this from the graph. Will update in case i find the cause.

Thanks all for your inputs.