我在产品和产品组之间存在多对多的关系。
使用EF4.1 Code First,在向ProductGroup添加产品/从ProductGroup中删除产品时,我会得到奇怪且不存在的结果。
我的观点完美无缺;它重新调整GroupId和List productIds。问题出在控制器中,我遍历productIds列表并分配/删除到ProductGroup。
以下是我的代码摘录,用于从ProductGroup中删除产品:
ProductGroup productGroup = _Repository.GetProductGroup(groupId);
using (var db = GetDbContext())
{
foreach (var pId in productIds)
{
Product p = _Repository.GetProduct(Convert.ToInt32(pId));
productGroup.Products.Remove(p);
db.Entry(productGroup).State = System.Data.EntityState.Modified;
p.ProductGroups.Remove(productGroup);
db.Entry(p).State = System.Data.EntityState.Modified;
db.SaveChanges();
}
}
基本上,我必须同时影响ProductGroup和单个产品以获得任何结果......然后结果是混合的。例如,在检查数据库表(ProductGroupProducts)时,只会删除一些记录,但我无法弄清楚哪些是哪种模式,哪些不是。
将产品分配到ProductGroup时遇到类似问题。代码几乎与明显的.Add()而不是.Remove()。
相同我在这里缺少什么?有人知道这样做的更好,并且希望更一致吗?
非常感谢提前!
拉杜
答案 0 :(得分:2)
什么是GetDbContext()
?如果这创建了新的上下文,那么db
显然是另一个上下文,而不是您在_Repository
中使用的上下文。 (如果它返回与_Repository
正在使用的相同的上下文,那么using
块很奇怪,因为它在最后处理了上下文,因此也破坏了_Repository
中的上下文。
您必须将productGroup
和p
附加到您正在进行修改的上下文中:
ProductGroup productGroup = _Repository.GetProductGroup(groupId);
using (var db = GetDbContext())
{
db.ProductGroups.Attach(productGroup);
foreach (var pId in productIds)
{
Product p = _Repository.GetProduct(Convert.ToInt32(pId));
db.Products.Attach(p);
productGroup.Products.Remove(p);
}
db.SaveChanges();
}
我已删除p.ProductGroups.Remove(productGroup)
,因为我认为EF会在您从群组中删除产品时自动执行此操作(但我不确定;您可以在调试器中查看这些集合以查看。)
如果GetDbContext()
确实创建了新的上下文,则重新考虑设计。您应该只有一个上下文用于此类操作(读取和更新)。
修改强>
这可能更容易:
ProductGroup productGroup = _Repository.GetProductGroup(groupId);
using (var db = GetDbContext())
{
db.ProductGroups.Attach(productGroup);
foreach (var pId in productIds)
{
var p = productGroup.Products
.SingleOrDefault(p1 => p1.ID == Convert.ToInt32(pId))
if (p != null)
productGroup.Products.Remove(p);
}
db.SaveChanges();
}
它可以为您保存产品的数据库查询。我假设你要么使用延迟加载,要么_Repository.GetProductGroup
对产品集合有Include
。