[英]Entity Framework 4.1. Updating many-to-many relationships. Is this the right way?
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
我认为不使用
Find
就可以做到这一点
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
. 您有以下三个数据库查询:1)
context.MarketCategories.Load()
(希望类别表很小,否则将无法通过,因为它将整个表加载到内存中),2) ...Find
和3) dbProd.Categories.Clear()
:必须是延迟加载,否则会崩溃,因为dbProd.Categories
为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
}
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. Union()
调用将保留所有现有产品,添加新产品,并更新重叠的产品。 Since your navigation property Categories
is probably defined as an ICollection<Category>
you have to use the ToList()
extension method during assignment. 由于导航属性
Categories
可能定义为ICollection<Category>
,因此在分配过程中必须使用ToList()
扩展方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.