c# – 在尝试保存更新时,由于相同的主键而附加实体时出错

前端之家收集整理的这篇文章主要介绍了c# – 在尝试保存更新时,由于相同的主键而附加实体时出错前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试保存对现有数据库条目的更新,但是当我这样做时,我收到错误

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;

猜你在找的C#相关文章