How to insert graph in Entity Framework with circular dependency

北城以北 提交于 2020-06-28 06:09:11

问题


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

来源:https://stackoverflow.com/questions/62425113/how-to-insert-graph-in-entity-framework-with-circular-dependency

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!