使用以下代码:
using (ICMSEntities db = new ICMSEntities())
{
productObj.Sectors.Clear();
int[] selected_sectors = cblSectors.Items.Cast<ListItem>()
.Where(n => n.Selected).Select(n => Convert.ToInt32(n.Value)).ToArray();
for (int i = 0; i < selected_sectors.Length; i++)
{
int SectorID = selected_sectors[i];
Sector sectorObj = db.Sectors.SingleOrDefault(x => x.sector_id == SectorID);
productObj.Sectors.Add(sectorObj);
}
db.SaveChanges();
Response.Redirect("~/Products.aspx", true);
}
我正在尝试更新多对多关系表。每个部门都可以拥有一组产品,每个产品都可以拥有一组部门。在尝试更新产品实体时,我会清除所有扇区,以防用户使用上面的.Clear()
从复选框列表中选择其他可用扇区。然后从复选框列表中读取并更新。我没有更新记录,而是使用新的自动递增ID在产品中获得一个新的相同行。所以它正在进行插入而不是更新,我从未指定.AddObject()
。
我在这里做错了什么?或者我该如何正确实现?
感谢。
答案 0 :(得分:0)
而不是:
Sector sectorObj = db.Sectors.SingleOrDefault(x => x.sector_id == SectorID);
这样做:
Sector sectorObj = db.Sectors.Find(SectorID);
如果您不希望代码使用.Find
进行数据库往返,请改用此LoadStub方法:http://www.ienablemuch.com/2011/08/entity-frameworks-nhibernate_02.html
public static class Helpers
{
public static Ent LoadStub<Ent>(this DbContext db, object id) where Ent : class
{
string primaryKeyName = typeof(Ent).Name + "Id";
return db.LoadStub<Ent>(primaryKeyName, id);
}
public static Ent LoadStub<Ent>(this DbContext db, string primaryKeyName, object id) where Ent: class
{
var cachedEnt =
db.ChangeTracker.Entries().Where(x => ObjectContext.GetObjectType(x.Entity.GetType()) == typeof(Ent)).SingleOrDefault(x =>
{
var entType = x.Entity.GetType();
var value = entType.InvokeMember(primaryKeyName, System.Reflection.BindingFlags.GetProperty, null, x.Entity, new object[] { });
return value.Equals(id);
});
if (cachedEnt != null)
{
return (Ent) cachedEnt.Entity;
}
else
{
Ent stub = (Ent) Activator.CreateInstance(typeof(Ent));
typeof(Ent).InvokeMember(primaryKeyName, System.Reflection.BindingFlags.SetProperty, null, stub, new object[] { id });
db.Entry(stub).State = EntityState.Unchanged;
return stub;
}
}
}
您的代码应如下所示:
Sector sectorObj = db.LoadStub<Sector>(SectorID);
示例用法:http://www.ienablemuch.com/2011/07/using-checkbox-list-on-aspnet-mvc-with_16.html
答案 1 :(得分:0)
我认为删除和重新创建不是一个好主意。此外,使用Clear
不会从内存中删除数据库。这是你要做的:
using (ICMSEntities db = new ICMSEntities())
{
foreach (ListItem item in cblSectors.Items)
{
int SectorID = item.Convert.ToInt32(item.Value);
if (item.Selected && !productObj.Sectors.Any(s => s.SectorID == SectorID))
{
Sector sectorObj = db.Sectors.Single(x => x.sector_id == SectorID);
productObj.Sectors.Add(sectorObj);
}
else if (!item.Selected && productObj.Sectors.Any(s => s.SectorID == SectorID))
{
var sector = productObj.Sectors.Single(s => s.SectorID == SectorID);
productObj.Sectors.Remove(sector);
}
}
db.SaveChanges();
Response.Redirect("~/Products.aspx", true);
}