1

This is how database structure looks like:

Vehicle has lot of CanNetworks and each CanNetwork has lot of ECUs. And that would save perfectly if that was only I have.

But, each vehicle also has one special ECU called gatewayECU so problem happens with saving because entity framework core does not know how to handle that scenario. It needs to insert vehicle before inserting ecus, but how to insert vehicle when ecu is not inserted.

This is what I tried: ignore (delete, invalidate) gatewayecu field (column is nullable in database), then I insert whole graph and then update vehicle with gatewayEcuId field I stored in some variable before doing anything.

Solution is not pretty. How to handle this scenario.

public class Vehicle : BaseEntity
{
    public Vehicle()
    {
        CANNetworks = new List<CANNetwork>();
    }

    public List<CANNetwork>? CANNetworks { get; set; }

    public ECU? GatewayECU { get; set; } = default!;
    public int? GatewayECUId { get; set; }
}

public class CANNetwork : BaseEntity
{
    public CANNetwork()
    {
        ECUs = new List<ECU>();
    }

    public string Name { get; set; } = default!;
    public ICollection<ECU>? ECUs { get; set; }

    public int VehicleId { get; set; }

    public Vehicle? Vehicle { get; set; } = default!;
}

public class ECU : BaseEntity
{
    public int CANNetworkId { get; set; }

    public CANNetwork? CANNetwork { get; set; } = default!;
}

This is ugly solution which I don't want:

public async Task<int> Insert(Vehicle vehicleDefinition, ECU vehicleGatewayECU)
{
    var result = -1;

    using (var transaction = _databaseContext.Database.BeginTransaction())
    {
        result = await Insert(vehicleDefinition);

        if (vehicleGatewayECU != null)
        {
            var ecu = await _databaseContext.ECUs.FirstOrDefaultAsync(x => x.Name == vehicleGatewayECU.Name && vehicleDefinition.Name == x.CANNetwork.Vehicle.Name);

            if (ecu != null)
            {
                vehicleDefinition.GatewayECUId = ecu.Id;
                result = await Update(vehicleDefinition);
                transaction.Commit();
                return result;
            }
        }
        else
        {
            transaction.Commit();
        }
    }

    return result;
}

EDIT: I am now thinking about changing table structure in a way to get rid of gatewayECU field on Vehicle, and put some flag IsGatewayEcu in ECU table

1
  • 2
    This has no solution with single SaveChanges, so changing the model to avoid circular references should be the best. Commented Jun 17, 2020 at 11:58

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.