实体框架,Pk,Fk,有时会出错

时间:2015-02-18 14:27:31

标签: c# entity-framework

当我想插入一些东西时,我偶尔会遇到这个错误:

  

INSERT语句与FOREIGN KEY约束冲突   " FK_dbo.Climb_dbo.DifficultGrade_DifficultGradeID&#34 ;.冲突   发生在数据库" ContosoUniversity2",table" dbo.DifficultGrade",   专栏' DifficultGradeID'。

     

声明已经终止。

但有时,我收到此错误,有时我不会收到此错误

我有这个插页:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(ClimbViewModel ModelViewClimb)
{
    try
    {
        if (ModelState.IsValid)
        {
            var climb = new Climb();
            UpdateCLimb(climb, ModelViewClimb);
            db.Climbs.Add(climb);

            db.SaveChanges();
            return RedirectToAction("Index");
        }
    }
    catch (RetryLimitExceededException /* dex */)
    {
        ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
    }

    ViewBag.Id = new SelectList(db.countries, "Id", "country_name", ModelViewClimb.Id);
    ViewBag.DifficultGradeID = new SelectList(db.DifficultGrades, "DifficultGradeID", "NameDifficult", ModelViewClimb.Id);
    return View(new ClimbViewModel() );
}

这些是我的模特:

public class Climb
{
    // public Climb climb { get; set; }

    [Key]
    public int climbID { get; set; }
    //[Display(Name="difficulty")]
    public string Name { get; set; }

    public int? UserProfileID { get; set; }
    public int? CountryID { get; set; }
    public int? DifficultGradeID { get; set; }

    public virtual UserProfile userProfile { get; set; }
    public virtual Country country { get; set; }
    public virtual DifficultGrade difficult { get; set; }
}

public class DifficultGrade
{
    [Key]
    public int DifficultGradeID { get; set; }
    [Display(Name = "difficulty")]
    public string NameDifficult { get; set; }
    public virtual ICollection<Climb> Climbs { get; set; }
    public virtual ICollection<Route> Routes { get; set; }
}

我还告诉我们要做什么,用户只需命名一个攀登并选择一个国家和一个困难的级别(简单,正常,艰难),所以两个下拉列表和一个文本框字段。通过添加新的爬升,我发现有时climbId和DifficultGradeID具有相同的ID。

1 个答案:

答案 0 :(得分:0)

对于这样的问题,请始终发布您的模型和您正在使用的任何自定义方法的代码,即UpdateClimb。没有这些信息,几乎不可能给你任何好的指导。

但是,在这种情况下,我可以根据错误对您的问题进行假设。最有可能的是,UpdateClimb除了其他内容之外,还会在Climb上设置一个带有列表的多对多导航属性。例如:

climb.SomeM2MNavigationProperty = someEnumerable;

如果该关系中已存在该枚举中的任何项目,则当您替换整​​个列表时,您将收到此错误,实体框架会将每个项目视为新添加的关系。当它插入这个新的重复记录时,数据库会尖叫。

在这种情况下,您应该做的是从现有关系中有选择地添加和删除项目。

// Remove items that are no longer related
entity.SomeM2MNavigationProperty.Where(m => !newRelationshipItemIds.Contains(m.Id))
    .ToList().ForEach(m => entity.SomeM2MNavigationProperty.Remove(m));

// Then you need to add any new relationships
var existingRelationshipItemIds = entity.SomeM2MNavigationProperty.Select(m => m.Id).ToList();
db.EntityDbSet.Where(m => newRelationshipItemIds.Except(existingRelationshipItemIds).Contains(m.Id))
    .ToList().ForEach(m => entity.SomeM2MNavigationProperty.Add(m));