插入子表使用EF和dbcontext获取外键错误

时间:2017-11-10 18:34:23

标签: c# entity-framework tsql

您好我是ASP MVC的新手,所以我有点难以解决这个问题。

表结构有一个作为父作业的作业,然后作为子作业在该作业(作业细节)中分配的任务。 jobsdetail表有一个foreignkey(jobsid)到jobs表。

当我尝试保存记录时,我得到了

  

异常详细信息:System.Data.SqlClient.SqlException:INSERT语句与FOREIGN KEY约束冲突" FK_dbo.JobDetails_dbo.Jobs_jobsid"。冲突发生在数据库" NavTracking",table" dbo.Jobs",column' Id'中。   该声明已被终止。"

我怀疑问题出现在:_context.JobDetail.Add(JobDetail); line因为它试图插入一个jobsid但不确定。

这是我的班级:

public class JobDetails
{
    public int Id { get; set; }

    [ForeignKey("jobsid")]
    public virtual Jobs Job { get; set; }

    public int jobsid { get; set; }

    public JobType jobtype { get; set; }

    public int jobtypeid { get; set; }

    public Status status { get; set; }

    public int? statusID { get; set; }

    public DateTime? ReqDate { get; set; }

    public int? EtcStatus { get; set; }

    public Analysts Analyst { get; set; }

    public int? analystID { get; set; }

    public Priority priority { get; set; }

    public int? priorityID { get; set; }

    public bool IsTaskComplete { get; set; }

    public string SpecialNotes { get; set; }
}

我的控制器保存记录:

    [HttpPost]
    public ActionResult SaveTask(JobTaskViewModel JobDetVM)
    {
        var jobex = _context.Job.SingleOrDefault(j => j.Id == 
        if (JobDetVM.Jobdetail.Id == 0)
        {
            JobDetVM.Jobdetail.jobsid=jobex.Id;
            _context.JobDetail.Add(JobDetVM.Jobdetail);
        }
        else
        {
            var jobdetailsInDB = _context.JobDetail.Single(t => t.Id == JobDetail.Id);
            jobdetailsInDB.jobsid = JobDetail.jobsid;
            jobdetailsInDB.jobtypeid = JobDetail.jobtypeid;
            jobdetailsInDB.statusID = JobDetail.statusID;
            jobdetailsInDB.ReqDate = JobDetail.ReqDate;
            jobdetailsInDB.EtcStatus = JobDetail.EtcStatus;
            jobdetailsInDB.analystID = JobDetail.analystID;
            jobdetailsInDB.priorityID = JobDetail.priorityID;
            jobdetailsInDB.IsTaskComplete = JobDetail.IsTaskComplete;
            jobdetailsInDB.SpecialNotes = JobDetail.SpecialNotes;
        }
        _context.SaveChanges();

        return RedirectToAction("Index", "Job");
    }

和发布数据的视图:

@using (Html.BeginForm("SaveTask", "Job"))
{
    <div class="form-group">
        @Html.LabelFor(m => m.Jobdetail.jobtypeid)
        @Html.DropDownListFor(m => m.Jobdetail.jobtypeid, new SelectList(Model.Jobtype, "Id", "JobTypeVal"), "Select Job Type", new { @class = "form-control" })
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Jobdetail.ReqDate)
        @Html.TextBoxFor(m => m.Jobdetail.ReqDate, new { @class = "form-control" })
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Jobdetail.EtcStatus)
        @Html.TextBoxFor(m => m.Jobdetail.EtcStatus, new { @class = "form-control" })
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Jobdetail.analystID)
        @Html.DropDownListFor(m => m.Jobdetail.analystID, new SelectList(Model.Analyst, "Id", "AnalystName"), "Select Analyst", new { @class = "form-control" })
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Jobdetail.priorityID)
        @Html.DropDownListFor(m => m.Jobdetail.priorityID, new SelectList(Model.Priority, "Id", "PriorityVal"), "Select Priority", new { @class = "form-control" })
    </div>

    <div class="form-group">
        @Html.LabelFor(m => m.Jobdetail.statusID)
        @Html.DropDownListFor(m => m.Jobdetail.statusID, new SelectList(Model.Status, "Id", "StatusVal"), "Select Status", new { @class = "form-control" })
    </div>

    <div class="form-group">
        @Html.LabelFor(m => m.Jobdetail.SpecialNotes)
        @Html.TextBoxFor(m => m.Jobdetail.SpecialNotes, new { @class = "form-control" })
    </div>


    @Html.HiddenFor(m => m.Jobdetail.Id)
    @Html.HiddenFor(m => m.Jobdetail.jobsid)
    <button type="submit" class="btn btn-primary">Save</button>

}

我的视图模型:

   public class JobTaskViewModel
    {
        public JobDetails Jobdetail { get; set; }

        public Jobs Job { get; set; }

        public int jobsID { get; set; }

        public IEnumerable<Status> Status { get; set; }

        public IEnumerable<Analysts> Analyst { get; set; }

        public IEnumerable<JobType> Jobtype { get; set; }

        public IEnumerable<Priority> Priority { get; set; }



    }

3 个答案:

答案 0 :(得分:2)

  

异常详细信息:System.Data.SqlClient.SqlException:INSERT语句与FOREIGN KEY约束冲突&#34; FK_dbo.JobDetails_dbo.Jobs_jobsid&#34;。冲突发生在数据库&#34; NavTracking&#34;,table&#34; dbo.Jobs&#34;,column&#39; Id&#39;中。该声明已被终止。&#34;

错误/异常非常清楚。您有一个名为NavTacking的数据库,其中constraint名为FK_dbo.JobDetails_dbo.Jobs_jobsid,该记录无法遵守。您正在将记录插入dob.JobDetails。插入失败是因为列(我认为)jobsid指定的值在dbo.Jobs列的表Id中不存在。

例如:

var jobDetails = new JobDetails
{
  jobsid = 12;
};

工作表:

Columns
Id    Name    Value
-------------------------
1     Test    Blah
2     Foo     Long Foo
3     Bar     Long Bar

以上jobDetails无法保存到数据库,因为Id 12没有json_array_elements()的作业。

答案 1 :(得分:0)

首先,我建议不要在视图中直接编辑实体模型。我会使用ViewModel pattern described herehere

您当前代码的问题是您没有获取JobDetails.Job,因此未对其进行跟踪。您可以attach it and set it's state或只是获取作业并使用它:

[HttpPost]
public ActionResult SaveTask(JobDetails JobDetail)
{
    var job = _context.Jobs.Single(j => j.Id == JobDetail.jobsid);
    if (JobDetail.Id == 0)
        JobDetail.Job = job;
        _context.JobDetail.Add(JobDetail);
    else
    {
        var jobdetailsInDB = _context.JobDetail
               .Include(jd => jd.Job)
               .Single(t => t.Id == JobDetail.Id);            
        jobdetailsInDB.jobtypeid = JobDetail.jobtypeid;
        jobdetailsInDB.statusID = JobDetail.statusID;
        jobdetailsInDB.ReqDate = JobDetail.ReqDate;
        jobdetailsInDB.EtcStatus = JobDetail.EtcStatus;
        jobdetailsInDB.analystID = JobDetail.analystID;
        jobdetailsInDB.priorityID = JobDetail.priorityID;
        jobdetailsInDB.IsTaskComplete = JobDetail.IsTaskComplete;
        jobdetailsInDB.SpecialNotes = JobDetail.SpecialNotes;
    }
    _context.SaveChanges();

    return RedirectToAction("Index", "Job");
}

答案 2 :(得分:0)

好的,我找到了答案。我需要将View中的Job_id传递回控制器,所以我的提交看起来像这样:

@Html.HiddenFor(m => m.Job.Id)
<button type="submit" value="Job.Id" class="btn btn-primary">Save</button>

感谢您的帮助