2017-03-24 20 views
6

Przenosimy do istniejącej aplikacji MVC6 EF6.Aktualizacja rdzenia szkieletu jednostki wielu do wielu

Czy istnieje prosta metoda w rdzeniu EF, aby zaktualizować wiele relacji?

Mój stary kod z EF6, w którym wyczyściliśmy listę i zastąpiliśmy ją nowymi danymi, już nie działa.

  var model = await _db.Products.FindAsync(vm.Product.ProductId); 

      model.Colors.Clear(); 

      model.Colors = _db.Colors.Where(x => 
      vm.ColorsSelected.Contains(x.ColorId)).ToList(); 

Odpowiedz

11

To będzie działać dla Ciebie.

uczynić klasa mieć związek w

public class ColorProduct 
{ 
    public int ProductId { get; set; } 
    public int ColorId { get; set; } 

    public Color Color { get; set; } 
    public Product Product { get; set; } 
} 

dodać zbiór ColorProduct do Produktu i kolorów klas

public ICollection<ColorProduct> ColorProducts { get; set; } 

następnie użyć tego rozszerzenia i wykonane, aby usunąć zaznaczone i dodaj nowo wybrane do listy:

public static void TryUpdateManyToMany<T, TKey>(this DbContext db, IEnumerable<T> currentItems, IEnumerable<T> newItems, Func<T, TKey> getKey) where T : class 
    { 
     db.Set<T>().RemoveRange(currentItems.Except(newItems, getKey)); 
     db.Set<T>().AddRange(newItems.Except(currentItems, getKey)); 
    } 

    public static IEnumerable<T> Except<T, TKey>(this IEnumerable<T> items, IEnumerable<T> other, Func<T, TKey> getKeyFunc) 
    { 
     return items 
      .GroupJoin(other, getKeyFunc, getKeyFunc, (item, tempItems) => new { item, tempItems }) 
      .SelectMany(t => t.tempItems.DefaultIfEmpty(), (t, temp) => new { t, temp }) 
      .Where(t => ReferenceEquals(null, t.temp) || t.temp.Equals(default(T))) 
      .Select(t => t.t.item); 
    } 

używanie tego wygląda tak

var model = _db.Products 
      .Include(x => x.ColorProducts) 
      .FirstOrDefault(x => x.ProductId == vm.Product.ProductId); 

_db.TryUpdateManyToMany(model.ColorProducts, vm.ColorsSelected 
.Select(x => new ColorProduct 
{ 
    ColorId = x, 
    ProductId = vm.Product.ProductId 
}), x => x.ColorId); 
+0

Wow, to jest niesamowite. Mogę użyć tego rozszerzenia we wszystkich moich projektach. Dziękuję za szybką odpowiedź. –

+0

Najważniejszą częścią tego rozwiązania (i problemu w kodzie OP) jest wywołanie "Include". –

+1

'Z wyjątkiem' rozszerzenie jest niesamowite, dzięki. –