我希望这是一个简单的解决方案。
我收集了大量信息,但可以跳过标题"问题"阅读实际问题。
在我的本地数据库中,我构建了一个表模式并用数据填充它们。
基本流程:
FORMS 表与 QUESTIONS 表格有一对多的关系
问题与 ANSWERS 表有一对多的关系。
QUESTIONS 表引用带有 FormId 的 FORMS 表。
ANSWERS 表使用 QuestionId
引用问题以下是 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来填充我的本地数据库。
现在,这样做了,因为所有内容都是使用实体框架引用和维护的。
我编写了您将在下面看到的代码,将此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吗?
一如既往,感谢任何帮助过的人。请不要无缘无故地请求downvote。如果需要,我可以附加更多信息。
附加是异常的堆栈跟踪。
这是一个NullReferenceException
答案 0 :(得分:2)
您不使用以下代码包含相关对象,有关详细信息,请阅读此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();