Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Linq和实体框架更新问题_C#_Asp.net_Sql Server_Linq_Entity Framework - Fatal编程技术网

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