PgAdmin导入/导出未将外键与实体框架保持

时间:2018-03-27 16:18:59

标签: c# postgresql entity-framework linq asp.net-core-webapi

我希望这是一个简单的解决方案。

我收集了大量信息,但可以跳过标题"问题"阅读实际问题。

在我的本地数据库中,我构建了一个表模式并用数据填充它们。

基本流程:

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

This is the NullReferenceException Stack trace This is the data in the QA database, it is there.

1 个答案:

答案 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();