수색…


소개

EF Core에서 Many to Many 관계를 업데이트하는 방법 :

MVC POST 편집 예제

여러 제품에 여러 색상을 사용할 수있는 Product 클래스가 있다고 가정 해 보겠습니다.

public class Product
{       
    public int ProductId { get; set; }
    public ICollection<ColorProduct> ColorProducts { get; set; }
}

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

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

public class Color
{      
    public int ColorId { get; set; }
    public ICollection<ColorProduct> ColorProducts { get; set; }
}

이 확장 프로그램을 사용하면 더 쉽게 사용할 수 있습니다.

public static class Extensions
{
    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);
    }
}

제품 색상 업데이트는 다음과 같습니다 (MVC 편집 POST 메소드).

[HttpPost]
public IActionResult Edit(ProductVm vm)
{
if (ModelState.IsValid)
    {
        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);

        db.SaveChanges();

        return RedirectToAction("Index");
    }   
   return View(vm);
}


public class ProductVm
{          
    public Product Product { get; set; }
    
    public IEnumerable<int> ColorsSelected { get; set; }      
}

코드는 최대한 단순화되었으며, 어떤 클래스에도 추가 속성이 없습니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow