繁体   English   中英

EF Core 不在子表中插入外键

[英]EF Core does not insert foreign key in child table

我有以下课程:

public class PresentingComplaintModel
{ 
    // for presenting complaints only
    [Key]
    public int ComplaintId { get; set; }
    public string Complaint { get; set; }
    public int? PatientId { get; set; }
    public Patient Patient { get; set; }
    public DateTime CreationDate { get; set; }
    public List<PatientComplaintQuestionAnswers> PatientComplaintQuestionAnswers { get; set; }
}

此类与此类具有一对多关系:

public class PatientComplaintQuestionAnswers
{ 
    [Key]
    public int Id { get; set; }
    public int? PresentingComplaintQuestionId { get; set; }
    public PresentingComplaintQuestionModel PresentingComplaintQuestionModel { get; set; }
    public bool Answer { get; set; }
    public int ComplaintId { get; set; } //from PresentingComplaintModel
    public PresentingComplaintModel PresentingComplaintModel {get;set;}
}

这个类有两个外键: PresentingComplaintQuestionIdComplaintId 问题是当我将PresentingComplaintModel对象插入数据库时​​,子表 ( PatientComplaintQuestionAnswers ) 接收数据但ComplaintId始终设置为 0。这意味着ComplaintId不是从PresentingComplaintModel类的主键中填充的。

我希望这具有非零主键值。 如何解决这个问题?

PresentingComplaintModel的水合如下。 此处ComplaintId始终为 0,因为正在创建新记录。

PresentingComplaintModel complaint = new();
List<PresentingComplaintQuestionModel> MasterQuestions { get; set; }
public PatientComplaintQuestionAnswers selectedItem1 { get; set; }

protected override async Task OnInitializedAsync()
{
    complaint.PatientComplaintQuestionAnswers = new List<PatientComplaintQuestionAnswers>();
    complaint.Complaint = "";
    complaint.CreationDate = DateTime.Now;
    complaint.PatientId = AppState.SelectedPatient.PatientId;
    MasterQuestions = await DataService.GetPresentingComplaintQuestionsAsync(); //get master questions.

    foreach (var q in MasterQuestions)
    {
        var ans = new PatientComplaintQuestionAnswers();
        ans.ComplaintId = complaint.ComplaintId;
        ans.PresentingComplaintQuestionId = q.PresentingComplaintQuestionId;
        ans.Answer = false;
        ans.PresentingComplaintQuestionModel = q;
        ans.PresentingComplaintModel = complaint; //reciprocal hydrating. see https://stackoverflow.com/questions/72293081/efcore-does-not-insert-foreign-key-in-child-table/72293303#72293303
        complaint.PatientComplaintQuestionAnswers.Add(ans);
    }
}

然后保存到数据库:

var res = await DataService.UpdatePresentingComplaintAsync(complaint);
...
...
public async Task<bool> UpdatePresentingComplaintAsync(PresentingComplaintModel complaint)
{
    int res = 0;

    using (var scope = _scopeFactory.CreateScope())
    {
        var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();

        try
        {
            context.PresentingComplaints.Update(complaint);
            res = await context.SaveChangesAsync();
        }
        catch (Exception ex)
        {
        }
    }

    if (res > 0)
        return true;
    else
        return false;
}

在数据库方面,我看到了这些插入。 请注意, ComplaintId列中全为 0:

数据库截图

通常这是缺乏“互惠”保湿。

public class MyParent()
{
    public MyParent()
    {
         this.TheKids = new List<MyChild>();
    }

    public long MyParentKey {get; set;} /* PK */


    public ICollection<MyChild> TheKids {get;set;}
}

public class MyChild()
{
  public long MyChildKey {get; set;} /* PK */
  public long MyParentKey {get;set;} /* FK to MyParent */

  public MyParent TheMyParent {get;set;} /* navigation property to MyParent */
}

当您水合“数据库中尚不存在”实体时..您必须做一些“互惠”

MyParent p1 = new MyParent();

MyChild c1 = new MyChild();

/* most people do this */
p1.TheKids.Add(c1);

/* the "reciprocal" that is sometimes missed */
c1.TheMyParent = p1;

(或者反之亦然,孩子获得“TheMyParent”集,但孩子没有添加到 MyParent.TheKids 集合中)

试试看(确保设置了所有倒数)

注意,我没有设置 MyChild.MyParentKey。

如果 MyParent 尚不存在,我会这样做。

..

EF 允许使用 FK 标量的“捷径”......如果它们是已知的。

例如。

public class Employee()
{
  public long EmployeeKey {get; set;} /* PK */
  public string LastName {get; set;} 
  public string FirstName {get; set;} 
  public long ParentDepartmentKey {get;set;} /* FK to Department */

  public Department ParentDepartment {get;set;} /* navigation property to Department */
}

如果我有上述课程,并且当我添加一个新员工时......并且员工必须将其部门设置为现有部门。

然后我可以做类似的事情

Employee emp = new Employee();
emp.LastName = "Smith";
emp.FirstName = "Mary";

emp.ParentDepartmentKey = 333; /* an already existing Department */

这样,我不必完全水合 emp.ParentDepartment OBJECT(导航属性)来添加 Employee。

因此,在将对象图提供给您的 EF dbcontext 并持久化更改之前,您需要了解“存在什么和不存在什么”。

好的,我找到了解决方法。 在这种情况下,似乎 EFCore 没有正确设置外键列。 所以我用明确的 ForeignKey 属性修改了 PatientComplaintQuestionAnswers 类:

public class PatientComplaintQuestionAnswers
{ 
    [Key]
    public int Id { get; set; }
    public int? PresentingComplaintQuestionId { get; set; }
    public PresentingComplaintQuestionModel PresentingComplaintQuestionModel { get; set; }
    public bool Answer { get; set; }
    public int ComplaintId { get; set; } //from PresentingComplaintModel
    public PresentingComplaintModel PresentingComplaintModel {get;set;}
}

public class PatientComplaintQuestionAnswers
    { //patient answers these questions in the patient presenting complaint form
        [Key]
        public int Id { get; set; }
        [ForeignKey("PresentingComplaintQuestionModel")]
        public int? PresentingComplaintQuestionId { get; set; }
        public PresentingComplaintQuestionModel PresentingComplaintQuestionModel { get; set; }
        public bool Answer { get; set; }
        [ForeignKey("PresentingComplaintModel")]
        public int ComplaintId { get; set; } //from PresentingComplaintModel
        public PresentingComplaintModel PresentingComplaintModel {get;set;}
    }

这修复了关系,并且 EFCore 也没有生成任何无关的列。

暂无
暂无

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

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