简体   繁体   English

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

[英]Entity Framework, Pk, Fk, sometimes getting error

I get sometimes this error, when I want to insert something: 当我想插入一些东西时,我偶尔会得到这个错误:

The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.Climb_dbo.DifficultGrade_DifficultGradeID". INSERT语句与FOREIGN KEY约束“FK_dbo.Climb_dbo.DifficultGrade_DifficultGradeID”冲突。 The conflict occurred in database "ContosoUniversity2", table "dbo.DifficultGrade", column 'DifficultGradeID'. 冲突发生在数据库“ContosoUniversity2”,表“dbo.DifficultGrade”,列“DifficultGradeID”中。

The statement has been terminated. 该语句已终止。

But sometimes, I get this error, and sometimes I dont get this error 但有时,我得到这个错误,有时我不会得到这个错误

I have this insert: 我有这个插入:

[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() );
}

These are my models: 这些是我的模特:

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

and

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

I also tell what is has to be, a user can just name a climb and select a country and a difficult level (easy, normal, hard) so two dropdownlists and one textbox field. 我还告诉我们要做什么,用户只需命名一个攀爬并选择一个国家和一个困难的级别(简单,正常,硬)所以两个下拉列表和一个文本框字段。 By adding a new climb, and I see that sometimes climbId and DifficultGradeID have the same id. 通过添加新的爬升,我看到有时climbId和DifficultGradeID具有相同的id。

Please, for questions like this, always post your models and the code for any custom methods you're using, ie UpdateClimb . 对于这样的问题,请始终发布您正在使用的任何自定义方法的模型和代码,即UpdateClimb It's next to impossible to give you any good guidance without such information. 没有这些信息,几乎不可能给你任何好的指导。

However, in this case, I can make an assumption about what your problem is based on the error. 但是,在这种情况下,我可以根据错误对您的问题进行假设。 Most likely, UpdateClimb , among other things, set's a many-to-many navigation property on Climb with a list directly. 最有可能的是, UpdateClimbClimb了一个带有列表的多对多导航属性。 For example: 例如:

climb.SomeM2MNavigationProperty = someEnumerable;

If any items in that enumerable already exists on the relationship, you'll get this error as when you replace the entire list, Entity Framework treats each item as a newly added relationship. 如果关系中已存在该枚举中的任何项目,则会在更换整个列表时收到此错误,实体框架会将每个项目视为新添加的关系。 When it inserts this new, duplicate record, the database screams. 当它插入这个新的重复记录时,数据库会尖叫。

What you should do instead in situations like this is selectively add and remove items form the existing relationships. 在这种情况下你应该做的是从现有关系中有选择地添加和删除项目。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM