Memorizzazione di entità con relazioni molti-a-molti mappate

1

Quando sviluppi una relazione molti-a-molti, creo 3 entità: Car, Part e un CarPart che contiene gli elenchi di entrambe le entità.

Sul lato client dell'applicazione voglio essere in grado di accedere direttamente a tutte le parti della macchina senza la necessità di usare gli oggetti many-to-many, per fare ciò uso la libreria AutoMapper.

// 1. Use Resourse to hide entity information from client    
CreateMap<Part, PartResource>()

// 2. Convert many-to-many entity (CarPart) to a simple parts-list 
CreateMap<CarPart, PartResource>()
    .ForMember(pr => pr.Name, opt => opt.MapFrom(cp => cp.Name));

CreateMap<Car, CarResource>()
    .ForMember(cr => cr.parts, opt => opt.MapFrom(c => c.CarParts)) // parts is a list of PartResource

Usando questa configurazione, ogni auto sul lato client avrà un elenco di Parti. Quando aggiungo una nuova auto, sto inviando di nuovo la macchina appena creata al server per eseguire il loop dell'elenco delle parti e creare e memorizzare manualmente le entità many-to-many (CarPart).

public async Task<CarResource> Post([FromBody] CarResourse resource) 
{
    var car = mapper.Map<CarResource, Car>(resource);
    await context.Cars.AddAsync(car);

    context.SaveChanges(); // car.Id is needed when creating the many-to-many entity

    foreach (var partResource in resource.Parts)
    {
        var carPart = new CarPart(car.Id, partResource.Id);

        await context.CarParts.AddAsync(carPart);
    }

    context.SaveChanges();

    return mapper.Map<Car, CarResource>(car);
}

Modelli:

public class Car
{
    public int Id { get; set; }
    public string Name { get; set; }
    public IList<CarPart> CarParts { get; set; }
}

public class Part
{
    public int Id { get; set; }
    public string Name { get; set; }
    public IList<CarPart> CarParts { get; set; }
}

public class CarPart
{
    public int CarId { get; set; }
    public Car Car { get; set; }
    public int PartId { get; set; }
    public Part Part { get; set; }
}

Quando si hanno più liste molti-a-molti questo metodo diventerà molto lungo, ci sono modi migliori per farlo?

    
posta Sam 03.07.2017 - 12:22
fonte

1 risposta

1

Attualmente, il core della struttura dell'entità non offre una soluzione "migliore".

Tuttavia, è ancora possibile accedere ai dati desiderati senza la tabella di giunzione. Prendi queste due classi (Ho notato che ho cambiato le liste):

public class Car
{
    public int Id { get; set; }
    public string Name { get; set; }
    public IList<Part> Parts { get; set; }
}

public class Part
{
    public int Id { get; set; }
    public string Name { get; set; }
    public IList<Car> Cars { get; set; }
}

Ora puoi usare il tuo dbcontext ( _db sotto) insieme a linq, per accedere ai dati che desideri.

Ottieni le parti di un'auto (Car Id = 1 )

_db.Car.Include(c => c.Parts).Where(c => c.Id == 1).Select(c => c.Parts);

Ottieni le auto in cui è presente una parte (Parte Id = 3 )

_db.Part.Include(p => p.Cars).Where(p => p.Id == 3).Select(p => p.Cars);

Verifica se una macchina ha una parte particolare (Car Id = 1 , Parte Id = 3 )

var partIds = _db.Car.Include(c => c.Parts)
                 .Where(c => c.Id == 1)
                 .Select(c => c.Parts.Id);
var hasPart = part.Contains(3);
    
risposta data 05.09.2018 - 22:57
fonte

Leggi altre domande sui tag