C# Linq和实体框架更新问题
使用以下代码:C# Linq和实体框架更新问题,c#,asp.net,sql-server,linq,entity-framework,C#,Asp.net,Sql Server,Linq,Entity Framework,使用以下代码: 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();
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);
}
使用(ICMSEntities db=new ICMSEntities())
{
productObj.Sectors.Clear();
int[]选定的_扇区=cblSectors.Items.Cast()
.Where(n=>n.Selected)。选择(n=>Convert.ToInt32(n.Value)).ToArray();
对于(int i=0;ix.Sector\u id==SectorID);
productObj.sections.Add(sectorObj);
}
db.SaveChanges();
Response.Redirect(“~/Products.aspx”,true);
}
我正在尝试更新多对多关系表。每个部门可以有一组产品,每个产品可以有一组部门。尝试更新产品实体时,我会清除所有扇区,以防用户使用上面的.Clear()
从复选框列表中选择其他可用扇区。然后从复选框列表中读取并更新。我没有更新记录,而是在产品中获得一个新的相同行,该行具有新的自动递增ID。因此,它执行插入而不是更新,并且我从未指定.AddObject()
我做错了什么?或者我应该如何正确地实现这一点
谢谢。代替这个:
Sector sectorObj = db.Sectors.SingleOrDefault(x => x.sector_id == SectorID);
这样做:
Sector sectorObj = db.Sectors.Find(SectorID);
如果您不希望您的代码引起与
.Find
的数据库往返,请改用此LoadStub方法:
公共静态类帮助程序
{
公共静态Ent LoadStub(此DbContext db,对象id),其中Ent:class
{
字符串primaryKeyName=typeof(Ent).Name+“Id”;
返回db.LoadStub(primaryKeyName,id);
}
公共静态Ent LoadStub(此DbContext db,字符串primaryKeyName,对象id),其中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,新对象[]{});
返回值。等于(id);
});
if(cachedEnt!=null)
{
返回(Ent)cachedEnt.实体;
}
否则
{
entstub=(Ent)Activator.CreateInstance(typeof(Ent));
typeof(Ent).InvokeMember(primaryKeyName,System.Reflection.BindingFlags.SetProperty,null,stub,新对象[]{id});
db.Entry(stub.State=EntityState.Unchanged;
返回存根;
}
}
}
您的代码应如下所示:
Sector sectorObj = db.LoadStub<Sector>(SectorID);
sectorObj=db.LoadStub(SectorID);
示例用法:我认为删除并重新创建不是一个好主意。另外,使用
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);
}
productObj.sections.Add(sectorObj)代码>我正在为现有productObj实体添加一个扇区实体。怎么了?这样我就可以更新连接表了它没有执行任何“清除”操作,但它会附加新创建的行。您没有更新,而是删除并创建了一个新对象。您能解释更多信息并提供一个示例吗?原始记录未从数据库中删除。因此,如果我将Saeed作为一个产品,并尝试更新它,我仍然会创建Saeed+另一个新行。嗨,谢谢你的回答。您能解释一下第一个LINQ查询的错误吗?由于此方法适用于网站的大部分部分。请告诉我您在db.Sectors中使用的Find
方法。Find
在哪个版本的linq中?或者linq2EF?Sector sectorObj=db.Sectors.SingleOrDefault(x=>x.Sector\u id==SectorID)代码>这实际上得到了我需要的扇区。Micheal,我能够得到合适的扇区对象。在products表中插入另一个产品的问题。@user1027620您的productObj是否来自具有活动上下文的对象?实体框架几乎只处理附加到上下文的对象。如果productObj是从内存中的对象构造的,那么即使ID与数据库中的现有行匹配,它也将被视为新的。在您编辑的productObj上执行此操作:productObj=db.Products.Find(productId)
,然后EF现在可以响应您对productObj及其集合(例如,扇区)的操作同一问题,在数据库中创建了一个新产品,而现有产品没有得到更新。您从哪里获得productObj?
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);
}