我包含了一堆信息,但请随意跳过标题“问题”以阅读实际问题。
简介
在我的本地数据库中,我构建了一个表模式并用数据填充它们。
基本流程:
FORMS 表与QUESTIONS 表具有一对多关系
QUESTIONS 与 ANSWERS 表具有一对多关系。
QUESTIONS 表引用了带有 FormId 的 FORMS 表。
ANSWERS 表使用 QuestionId 引用 QUESTIONS
这是FORMS 和QUESTIONS 表的代码。
public class AppointmentForm
{
[Key]
public long Id { get; set; }
public string FormName { get; set; }
public int Order { get; set; }
public List<AppointmentQuestion> Questions { get; set; }
}
public class AppointmentQuestion
{
[Key]
public long Id { get; set; }
[ForeignKey("FormId")]
public virtual AppointmentForm Form { get; set; }
public long FormId { get; set; }
public int Order { get; set; }
public bool? Required { get; set; } = false;
public string Question { get; set; }
public virtual List<AppointmentAnswer> Answers { get; set; }
}
因此,我使用 PostMan 来填充我的本地数据库。
现在,这成功了,因为所有内容都通过 Entity Framework 进行引用和维护。
我编写了您将在下面看到的代码,以将此 JSON 结构发送到客户端。
{
"forms": [
{
"id": 1,
"formName": "Inclusion",
"order": 1,
"questions": [1, 2]
}
],
"questions": [
{
"id": 1,
"formId": 1,
"order": 1,
"required": true,
"question": "Are you able to go for a walk of at least 15 minutes?",
"answers": [1, 2, 3, 4, 5]
}
],
"answers": [
{
"id": 1,
"questionId": 1,
"typeId": 2,
"label": "Unable to do",
"order": 1
},
{
"id": 2,
"questionId": 1,
"typeId": 2,
"label": "Without much difficulty",
"order": 2
},
{
"id": 3,
"questionId": 1,
"typeId": 2,
"label": "With some difficulty",
"order": 3
},
{
"id": 4,
"questionId": 1,
"typeId": 2,
"label": "With a little difficulty",
"order": 4
},
{
"id": 5,
"questionId": 1,
"typeId": 2,
"label": "Without any difficulty",
"order": 5
}
],
"types": [
{
"id": 1,
"type": "Manual enter"
},
{
"id": 2,
"type": "Multiple choice"
}
]
}
要创建它,我会使用以下脚本(否则一切都会被嵌套)
public async Task<IActionResult> GetModelNormalized()
{
AppointmentModelNormalized Model = new AppointmentModelNormalized();
List<AppointmentForm> Forms = await _formManager.GetAppointmentFormsAsync();
List<AppointmentAnswerType> Types = await _typeManager.GetAppointmentAnswerTypesAsync();
foreach(AppointmentForm f in Forms)
{
AppointmentFormReference _f = new AppointmentFormReference() {
Id = f.Id,
FormName = f.FormName,
Order = f.Order
};
foreach(AppointmentQuestion q in f.Questions)
{
_f.Questions.Add(q.Id);
AppointmentQuestionReference _q = new AppointmentQuestionReference()
{
Id = q.Id,
Question = q.Question,
FormId = q.FormId,
Order = q.Order,
Required = q.Required
};
foreach(AppointmentAnswer a in q.Answers)
{
_q.Answers.Add(a.Id);
AppointmentAnswerReference _a = new AppointmentAnswerReference()
{
Id = a.Id,
Label = a.Label,
Order = a.Order,
QuestionId = a.QuestionId,
TypeId = a.TypeId
};
Model.Answers.Add(_a);
}
Model.Questions.Add(_q);
}
Model.Forms.Add(_f);
}
Model.Types = Types;
return Ok(Model);
}
在我的本地环境中,这一切都完美无缺。
问题
当我去测试 QA 时,我使用 PgAdmin4 导出了我的数据,然后将 csv 文件导入到 QA 数据库中。
现在,带有 foreach(AppointmentQuestion q in f.Questions)
的代码行不起作用,因为 FK 没有随导出/导入一起转移。
我不明白为什么会这样,因为 FK 都是一样的。
是否有更好的导出和导入数据的方式来保持 FK 关系?
如有必要,我可以像抓表格一样抓取所有问题和答案。 List<AppointmentForm> Forms = await _formManager.GetAppointmentFormsAsync();
但是 linq 不会为我做这些吗?我的意思是这就是虚拟方法的意义所在?它在被调用时被创建,至少我是这么认为的。我应该编写自定义 getter 和 setter 吗?
附件是异常的堆栈跟踪。这是一个NullReferenceException
.
最佳答案
您不包括您的相关对象使用以下代码,有关更多信息,请阅读此 answer
_context.AppointmentForms.Include(x => x.Questions ).Include(x => x.Questions.Select(q => q.Answers)).ToListAsync();
从 Christian4423 编辑:
我能够让它用语法做同样的事情。
List<AppointmentForm> Forms = await _context.AppointmentForms
.Include("Questions.Answers")
.ToListAsync();
关于c# - PgAdmin Import/Export 没有使用 Entity Framework 保留外键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49517887/