如何处理具有数据传输所需导航属性的实体框架模型?

问题描述 投票:0回答:1

我的数据库中有两个表:

  • 配置(父级)

    • id(PK)

    • 姓名

  • 配置警报(子级)

    • id(PK)

    • ConfigurationId(PK、FK 配置)

    • 留言

我已经通过 scaffolding 使用自定义模板生成了 Entity Framework Core 的模型:

public partial class Configuration
{
    public int Id { get; set; }
    public string Name { get; set; } = null!;
    public virtual ICollection<ConfigurationAlert> ConfigurationAlerts { get; set; } = new List<ConfigurationAlert>();
}

public partial class ConfigurationAlert
{
    public int Id { get; set; }
    public int? ConfigurationId { get; set; }
    public string Message{ get; set; }
    public virtual Configuration ConfigurationIdNavigation { get; set; } = null!;
}

客户端(Angular 应用程序)我通过 HTTP 调用检索所有配置及其警报,该调用到达服务器并使用 EF 上下文查询数据库并返回实体。 ConfigurationAlert 实体返回到客户端而无需 ConfigurationIdNavigation,这对我来说没问题。

问题是,当我将修改后的 Configurations+ConfigurationAlerts 发送回服务器时,出现错误“发生一个或多个错误:ConfigurationAlerts[0].ConfigurationIdNavigation - ConfigurationIdNavigation 字段为必填项。”

我可以使用自定义模板解决使 ConfigurationIdNavigation 可为空的问题:

public virtual Configuration? ConfigurationIdNavigation { get; set; } = null!;

但我认为这不是正确的解决方案,所以我正在寻找建议。

我是否应该复制创建 ConfigurationViewModel 和 ConfigurationAlertViewModel 的实体并将它们用作 DTO? (还有很多其他模型,所以代码会很多)

或者?

提前谢谢您。

c# angular entity-framework entity-framework-core asp.net-core-mvc
1个回答
0
投票

我应该复制创建 ConfigurationViewModel 的实体并 ConfigurationAlertViewModel 并将它们用作 DTO? (有很多的 其他型号,所以代码会很多)

嗯,根据您共享的代码片段,您的描述是正确的,使

ConfigurationIdNavigation
可为空并不是理想的解决方案,因为它引入了潜在的数据完整性问题。

根据场景,两种方式都可以解决。

首先,您可以将 ConfigurationIdNavigation 属性包含在查询中,而不是在检索数据时排除它。这可确保填充导航属性并避免保存更改时出现错误。所以我们可以这样做:

var configurations = _context.Configurations
    .Include(c => c.ConfigurationAlerts)
    .ToList();

您可以考虑的另一种方法是使用视图模型或 DTO(数据传输对象)。因为,它将数据库模型与 API 合约解耦,从而可以更好地控制向客户端发送和从客户端接收的数据。虽然它可能涉及一些额外的代码,但它提供了诸如提高灵活性、减少有效负载大小和增强安全性等优点。

为了实现这一点,我们可以这样做:

public class ConfigurationViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<ConfigurationAlertViewModel> ConfigurationAlerts { get; set; }
}

public class ConfigurationAlertViewModel
{
    public int Id { get; set; }
    public string Message { get; set; }
}

注意: 请记住,在向客户端发送数据时,请将数据库实体映射到视图模型。另外,当从客户端接收数据时,在保存视图模型之前将它们映射回数据库实体。请参阅此官方文档以获取更多资源。

© www.soinside.com 2019 - 2024. All rights reserved.