Attaching an entity of type ‘FFInfo.DAL.Location’ Failed because another entity of the same type already has the same primary key value. This can happen when using the ‘Attach’ method or setting the state of an entity to ‘Unchanged’ or ‘Modified’ if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the ‘Add’ method or the ‘Added’ entity state to track the graph and then set the state of non-new entities to ‘Unchanged’ or ‘Modified’ as appropriate.
这是我的控制器代码.我正在使用的保存方法与我在其他几个方面使用的保存方法相同,可以毫无问题地更新数据.
[HttpPost,ValidateAntiForgeryToken] public ActionResult EditLocation(AddEditLocationVM model,HttpPostedFileBase MapFile) { try { using (var db = new GeographyContext()) { model.Sections = new SelectList(db.Sections.Where(s => s.ID > 1).OrderBy(s => s.Title),"ID","Title").ToList(); model.GeographyTypes = new SelectList(db.GeographyTypes.Where(gt => gt.SectionID == model.Section).OrderBy(gt => gt.Name),"Name").ToList(); model.ParentLocations = new SelectList(db.Locations.Where(l => l.SectionID == model.Section).OrderBy(l => l.Name),"Name").ToList(); if (MapFile != null) { if (FileHelper.IsNotValidImage(MapFile)) { ModelState.AddModelError("Invaalid File Type","Images must be JPG,GIF,or PNG files."); } } if (ModelState.IsValid) { if (MapFile != null) { var SectionRoute = db.Sections.Where(s => s.ID == model.Section).Select(s => s.Route).First(); model.MapFileID = FileHelper.UploadFile("Images/" + SectionRoute + "/Maps/" + MapFile.FileName.ToList(),"site",MapFile); } if (model.ParentLocation == 0) { model.ParentLocation = null; } var UpdatedLocation = new Location() { Description = model.Description,GeographyTypeID = model.GeographyType,ID = model.ID,MapFileID = model.MapFileID,Name = model.Name,ParentLocationID = model.ParentLocation,SectionID = model.Section }; db.Entry(UpdatedLocation).State = EntityState.Modified; db.SaveChanges(); ViewBag.Results = "Location information updated."; } return View(model); } } catch (Exception ex) { ErrorSignal.FromCurrentContext().Raise(ex); model.Sections = Enumerable.Empty<SelectListItem>(); ViewBag.Results = "Error updating location informaiton,please try again later."; return View(model); } }
这是我的位置实体代码:
public class Location { [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int ID { get; set; } [required,Index("IX_Location",1,IsUnique = true)] public string Name { get; set; } [Index("IX_Location",2,IsUnique = true)] public Int16 SectionID { get; set; } [Column(TypeName = "varchar(MAX)")] public string Description { get; set; } public Int16 GeographyTypeID { get; set; } public int? MapFileID { get; set; } public int? ParentLocationID { get; set; } [ForeignKey("SectionID")] public Section Section { get; set; } [ForeignKey("GeographyTypeID")] public GeographyType GeographyType { get; set; } [ForeignKey("MapFileID")] public File Map { get; set; } [ForeignKey("ParentLocationID")] public Location ParentLocation { get; set; } public ICollection<LocationTransitionPoint> TransitionPoints { get; set; } }
这是我第一次尝试更新这样一个更复杂的实体,但是从我在网上找到的内容我看不出有什么不对.
解决方法
问题是
model.ParentLocations = new SelectList(db.Locations.Where(l => l.SectionID == model.Section).OrderBy(l => l.Name),"Name").ToList();
在上面的行中你以某种方式加载了它的ID为model.ID的Location
然后在
var UpdatedLocation = new Location() { Description = model.Description,SectionID = model.Section }; db.Entry(UpdatedLocation).State = EntityState.Modified;
您正在创建一个新位置并尝试将其附加到上下文(通过将其状态设置为已修改),但您已将另一个具有精确主键的Location实体作为UpdatedLocation加载到内存中,这会导致异常.
var UpdateLocation = db.Locations.First(l => l.ID == model.ID); // var UpdateLocation = db.Locations.Find(model.ID); maybe a better option UpdatedLocation.Description = model.Description; UpdatedLocation.GeographyTypeID = model.GeographyType; UpdatedLocation.MapFileID = model.MapFileID; UpdatedLocation.Name = model.Name; UpdatedLocation.ParentLocationID = model.ParentLocation; UpdatedLocation.SectionID = model.Section;