C# 实体框架,Pk,Fk,有时出错

C# 实体框架,Pk,Fk,有时出错,c#,entity-framework,C#,Entity Framework,当我想插入某些内容时,有时会出现以下错误: INSERT语句与外键约束冲突 “FK_dbo.攀登_dbo.艰难的前进_艰难的前进”。冲突 发生在数据库“ContosoUniversity2”表“dbo.HardicultGrade”中, 列'HardicultGradeId' 声明已终止 但是有时候,我会犯这个错误,有时候我不会犯这个错误 我有以下插页: [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create(ClimbV

当我想插入某些内容时,有时会出现以下错误:

INSERT语句与外键约束冲突 “FK_dbo.攀登_dbo.艰难的前进_艰难的前进”。冲突 发生在数据库“ContosoUniversity2”表“dbo.HardicultGrade”中, 列'HardicultGradeId'

声明已终止

但是有时候,我会犯这个错误,有时候我不会犯这个错误

我有以下插页:

[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 int-DifficultGradeID{get;set;}
[显示(Name=“难度”)]
公共字符串名称{get;set;}
公共虚拟ICollection爬升{get;set;}
公共虚拟ICollection路由{get;set;}
}

我还告诉什么是必须的,用户可以只命名一个攀登和选择一个国家和一个困难的水平(容易,正常,难),所以两个下拉列表和一个文本框字段。通过添加一个新的爬升,我发现有时爬升id和困难爬升id具有相同的id。

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

但是,在这种情况下,我可以根据错误假设您的问题是什么。最有可能的是,
UpdateClimb
gramb
上直接使用列表设置多对多导航属性。例如:

climb.SomeM2MNavigationProperty = someEnumerable;
如果关系中已存在该可枚举项中的任何项,则会出现此错误,因为在替换整个列表时,Entity Framework会将每个项视为新添加的关系。当它插入这个新的重复记录时,数据库会发出尖叫声

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

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

当您收到错误时,
难处理的RADEID
是什么?您确定正在选择它吗?如果它不可为null(比如,一个
int
),它将默认为0,使您的模型有效。这可能是您的问题。在
DbContext
类中,将
Database.Log
属性设置为
=msg=>Console.WriteLine(msg)。这样,您将记录数据库语句(包括传递的值)。现在您可以确定问题发生的位置,因为您知道传递的值。??有人会很好的
// 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));