Glen
Glen

Reputation: 331

ef core may to many update with extra filed

My mode class:

public class AccountCustomer
{    
        public bool IsMain { get; set; }
        public int AccountId { get; set; }
        public Account Account { get; set; }

        public int CustomerId { get; set; }
        public Customer Customer { get; set; } 
}

public class Account
{    
       
        public int Id { get; set; }
         public strig No{ get; set; }
        ..other fields
       public ICollection<AccountCustomer> AccCustomer { get; set; } = new List<AccountCustomer>();
}

public class Customer
{    
       
        public int Id { get; set; }
         public strig Name{ get; set; }
        ..other fields
    public ICollection<AccountCustomer> AccCustomer { get; set; } = new List<AccountCustomer>();
}

I found soluton here and i have implemented same later i found that it is for without extra column

Many to many ef core updaate

Please let meknow how to do update... Am using latest ef 5 preview

My code :

_context.Set<AccountCustomer>().UpdateLinks(ac => ac.AccountId, account.Id,
                ac => ac.CustomerId, account.AccCustomer .Select(ac => ac.CustomerId));

Upvotes: 1

Views: 89

Answers (1)

Michael Wang
Michael Wang

Reputation: 4022

Codes of ManyToMany Update Extensions

Remove the unselected item and add new item to list.

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.ExceptThat(newItems, getKey));
        db.Set<T>().AddRange(newItems.ExceptThat(currentItems, getKey));
    }

    private static IEnumerable<T> ExceptThat<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);
    }
}

Codes of Update ViewModel

The update view pass it to action via request.

public class AccountCustomerVM
{
    public bool IsMain { get; set; }
    public Account Account { get; set; }
    public List<int> Customers { get; set; }
}

Codes of Update Action

    [HttpPut]
    public IActionResult Update(AccountCustomerVM accountCustomerVM)
    {
        var model = _context.Accounts.Include(x => x.AccCustomer).FirstOrDefault(x => x.Id == accountCustomerVM.Account.Id);
        _context.TryUpdateManyToMany(model.AccCustomer, accountCustomerVM.Customers
            .Select(x => new AccountCustomer
            {
                IsMain = accountCustomerVM.IsMain,
                CustomerId = x,
                AccountId = accountCustomerVM.Account.Id
            }), x => x.CustomerId);
        _context.SaveChanges();
        return Ok();
    }

Upvotes: 1

Related Questions