4.1.实体框架更新多对多关系.这条路对吗?

本文关键字:条路 关系 框架 更新 实体 | 更新日期: 2023-09-27 18:16:58

下面的代码可以工作,但是,我怀疑我遗漏了一些东西。有没有"更好"的方法?

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

我认为不使用Find

4.1.实体框架更新多对多关系.这条路对吗?

就可以做到这一点

您有三个数据库查询:1)context.MarketCategories.Load()(希望类别表很小,否则这将是一个不去,因为它将整个表加载到内存中),2)...Find和3)dbProd.Categories.Clear():这里必须涉及延迟加载,否则这将崩溃,因为dbProd.Categories将是null

使用单个数据库查询进行更新的替代方法如下:

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
}

我相信你可以这样做:

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

Union()调用将保留任何现有产品,添加新产品,并更新重叠的产品。由于您的导航属性Categories可能被定义为ICollection<Category>,因此您必须在分配期间使用ToList()扩展方法。