Saving multiple objects with same object property EF core

.net-core asp.net-core c# entity-framework-core

Question

I have this situation: I have a MasterPlanComponent object that holds multiple objectives. These objectives hold multiple targets.

Upon creating a masterPlanComponent (with 2 objectives) we create 4 targets for both of those objectives.

This is what that's supposed to look like:

  • 1 component > 2 objectives > 8 targets (4 for one, 4 for the other, targets are blank and just need to be created in the database)

The problem with the below code is that only one set of 4 targets are created, and only for the second objective.

public async Task<MasterPlanComponent> CreateMasterPlanComponent(int masterPlanId, CreateMasterPlanComponentCommand command) 
{

    var masterPlan  = await _context.MasterPlans
        .Include(mp => mp.Components)
        .Include(mp => mp.Objectives)
        .SingleOrDefaultAsync(m => m.MasterPlanId == masterPlanId);

        var targets = new  List<ObjectiveNetTarget>();
    //creating new targets and setting two of their fields
    for (int i = 0 ; i < 4 ;  i++)
    {
        targets.Add(new ObjectiveNetTarget
        {
            CustomerMarketSegment = command.Scope.CustomerMarketSegment,
            OrganizationUnit = new OrganizationUnitRef
            {
                Name = "Sales",
                Code = "1251"

            }
        });

    }
    var masterPlanComponent = Mapper.Map<CreateMasterPlanComponentCommand, MasterPlanComponent>(command);
    foreach (var objective in masterPlanComponent.Objectives)
    {
        objective.TargetValues = new List<ObjectiveNetTarget>(targets);
    }

    masterPlanComponent.Status = MasterPlanComponentStatuses.New;
    masterPlan.Components.Add(masterPlanComponent);
    masterPlan.Objectives = masterPlan.Objectives.Concat(masterPlanComponent.Objectives).ToList();
    //masterPlanComponent.Objectives targets, I can see that both of them have 4 net targets as it should be
    await _context.SaveChangesAsync();

    _logger.LogInformation("New master plan component created.");
    _logger.LogInformation("Master plan component id: " + masterPlanComponent.ComponentId.ToString());
    //after I try to save the context however, only one of them has it. 
    return masterPlanComponent;
}

this code results in only 4 targets being written in the database each of them pointing to only one (the last one) of the objectives

1
0
3/12/2020 1:36:16 PM

Popular Answer

This sounds like it is caused because you are creating the targets ahead of time, and then passing them to each objective. When you pass the targets you created to the first objective, EF starts tracking them and marks them as to-be-inserted. When you pass the same csharp objects by ref to the 2nd objective, they are already marked as to-be-inserted and are simply updated to be referencing the 2nd objective rather than the first.

Try creating new target objects in csharp for each objective. EF will only insert 1 row : 1 csharp object reference.

1
3/12/2020 1:40:27 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow