尝试保存更新时由于主键相同而附加实体时出错 [英] Error attaching entity because of same primary key when trying to save an update

查看:102
本文介绍了尝试保存更新时由于主键相同而附加实体时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将更新保存到现有数据库条目,但是当我收到错误消息时:

I am trying to save an update to an existing database entry but when I do I get the error:


附加一个实体类型 FFInfo.DAL.Location失败,因为相同类型的另一个实体已经具有相同的主键值。如果图形中的任何实体具有相互冲突的键值,则使用附加方法或将实体的状态设置为不变或已修改时,可能会发生这种情况。这可能是因为某些实体是新实体,尚未收到数据库生成的键值。在这种情况下,请使用添加方法或已添加实体状态来跟踪图形,然后根据需要将非新实体的状态设置为未更改或已修改。

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.

这是我控制器的代码。我使用的保存方法与我在其他几个区域中使用的保存方法相同,都没有问题。

This is my controller's code. The save method I am using is the same I use in a few other areas to update data with no problems.

[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), "ID", "Name").ToList();
            model.ParentLocations = new SelectList(db.Locations.Where(l => l.SectionID == model.Section).OrderBy(l => l.Name), "ID", "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);
    }
}

这是我的位置实体代码:

This is my Location Entity code:

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

这是我第一次尝试更新这样的更复杂的实体,但是从网上发现的东西来看,我看不到任何错误。

This is my first time trying to update a more complex entity like this but from what I have found on the web I can not see anything wrong.

推荐答案

您不能有两个实体(相同类型)

You can not have two entities (same type) with same primary keys in memory in Entity Framework.

问题是

model.ParentLocations = new SelectList(db.Locations.Where(l => l.SectionID == model.Section).OrderBy(l => l.Name), "ID", "Name").ToList();

在上面的行中,您以某种方式加载了 Location ID model.ID

in above line you somehow have loaded the Location which its ID is model.ID

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;

您正在创建新的位置并尝试将其附加到上下文(通过将其状态设置为修改),但是您已经加载了另一个 Location 实体,其确切主键为 UpdatedLocation 放入内存中,这会导致异常。

You are creating a new Location and trying to attach it to context (by setting it's state as modified), but you have loaded another Location entity with exact primary key as UpdatedLocation into memory somewhere and this cause the exception.

尝试获取位置,然后更改绳索。

Try fetching the the location and then change the roperties.

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;

这篇关于尝试保存更新时由于主键相同而附加实体时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆