Entity Database Kernel Updates Many For Many

We are porting an existing MVC6 EF6 application to the kernel.

Is there a simple method in the EF core to update many relationships?

My old code from EF6, where we clear the list and overwrite it with new data, no longer works.

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

            model.Colors.Clear();

            model.Colors =  _db.Colors.Where(x => 
            vm.ColorsSelected.Contains(x.ColorId)).ToList();
+6
source share
1 answer

This will work for you.

make a class to relate to

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

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

add the ColorProduct collection to the Product and Color classes

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

Then use this extension i made to remove the unselected and add the newly selected to the list

    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);
    }

using it looks like

 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);
+11
source

Source: https://habr.com/ru/post/1015985/


All Articles