Entity Framework 4.1. Updating many-to-many relationships. Is this the right way?

萝らか妹 提交于 2019-12-10 23:14:47

问题


The code below works, however, I suspect that I'm missing something. Is there a 'better' way?

    private void UpdateNew(MarketProduct marketproduct)
    {
        context.MarketCategories.Load();
        MarketProduct dbProd = context.MarketProducts.Find(marketproduct.Id);
        dbProd.Categories.Clear();
        foreach (var c in marketproduct.Categories ?? Enumerable.Empty<MarketCategory>())
        {
            var cc = context.MarketCategories.Find(c.Id);
            dbProd.Categories.Add(cc);
        }
        context.Entry(dbProd).CurrentValues.SetValues(marketproduct);
    }

I thought it would be possible to do this without using Find


回答1:


You have three database queries: 1) context.MarketCategories.Load() (hopefully the category table is small, otherwise this would be a no-go as it loads the whole table into memory), 2) ...Find and 3) dbProd.Categories.Clear(): Here must be a lazy loading involved, otherwise this would crash because dbProd.Categories would be null.

An alternative to update with a single database query is the following:

private void UpdateNew(MarketProduct marketproduct)
{
    MarketProduct dbProd = context.MarketProducts
        .Include(p => p.Categories)
        .Single(p => p.Id == marketproduct.Id);

    var categories = marketproduct.Categories 
                     ?? Enumerable.Empty<MarketCategory>();
    foreach (var category in categories)
    {
        if (!dbProd.Categories.Any(c => c.Id == category.Id))
        {
            // means: category is new
            context.MarketCategories.Attach(category);
            dbProd.Categories.Add(category);
        }
    }
    foreach (var category in dbProd.Categories.ToList())
    {
        if (!categories.Any(c => c.Id == category.Id))
            // means: category has been removed
            dbProd.Categories.Remove(category);
    }

    context.Entry(dbProd).CurrentValues.SetValues(marketproduct);

    // context.SaveChanges() somewhere
}



回答2:


I believe you could just do this:

var dbProd = context.MarketProducts.Find(marketproduct.Id);
dbProd.Categories = dbProd.Categories
    .Union(marketproduct.Categories).ToList();

context.SaveChanges();

The Union() call will keep any existing products, add new ones, and update ones that overlap. Since your navigation property Categories is probably defined as an ICollection<Category> you have to use the ToList() extension method during assignment.



来源:https://stackoverflow.com/questions/8417824/entity-framework-4-1-updating-many-to-many-relationships-is-this-the-right-way

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!