在干净的架构中处理模型和实体的正确方法是什么?

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

因此,我正在尝试为新的 .NET 应用程序设置所有基础知识。这是一个 Blazor 应用程序,使用干净的架构和代码优先的 EF Core 创建。

在我的域层中,我定义了一些实体,这些实体将被 EF Core 用于生成数据库。在演示/WebUI 层中,我创建了一个模型文件夹,可以将其提供给 razor 文件。最初的想法是在检索数据时直接从实体映射到模型。

当在应用程序层中为我的服务创建接口时,我意识到应用程序层不应该访问表示层。因此我无法拥有像

Task<SomeModel> GetSomeModelByIdAsync(int id);
这样的界面。我必须返回该实体,但我不希望它一直发送到外层,对吗?

处理这个问题的正确方法是什么?我应该将模型移至应用程序层,还是创建表示层可以映射到模型的 DTO?这只是一个业余爱好项目,所以我可以慢慢来,把事情做得比应有的更好。是的,我可能想太多了,否则还有什么乐趣呢?

c# asp.net-core entity-framework-core blazor clean-architecture
1个回答
0
投票

一般来说,您应该首先根据您的应用程序需求设计您的核心域实体。 如果以天气预报为例,我们可以这样定义它。 使用 Guid 作为记录 Id 并使用小数作为温度是原始的痴迷,应该避免。 不要让您的数据存储决定您的应用程序设计。

public sealed record DmoWeatherForecast
{
    public WeatherForecastId WeatherForecastId { get; init; } = WeatherForecastId.NewEntity;
    public DateOnly Date { get; init; }
    public Temperature Temperature { get; set; } = new(0);
    public string? Summary { get; set; }
}

哪里

WeatherForecastId
是:

public readonly record struct WeatherForecastId
{
    public Guid Value { get; init; }
    public object KeyValue => this.Value;

    public WeatherForecastId(Guid value)
        => this.Value = value;

    public static WeatherForecastId NewEntity
        => new(Guid.Empty);
}

并且

Temperature
是:

public record Temperature
{
    public decimal TemperatureC { get; init; }
    public decimal TemperatureF => 32 + (this.TemperatureC / 0.5556m);

    public Temperature() { }

    public Temperature(decimal temperature)
    {
        this.TemperatureC = temperature;
    }
}

在基础设施层,我们需要依靠原语来适应数据存储:

public sealed record DboWeatherForecast
{
    [Key] public Guid WeatherForecastID { get; init; } = Guid.Empty;
    public DateTime Date { get; init; }
    public decimal Temperature { get; set; }
    public string? Summary { get; set; }
}

还有一个映射类:

public sealed class DboWeatherForecastMap : IDboEntityMap<DboWeatherForecast, DmoWeatherForecast>
{
    public DmoWeatherForecast MapTo(DboWeatherForecast item)
        => Map(item);

    public DboWeatherForecast MapTo(DmoWeatherForecast item)
        => Map(item);

    public static DmoWeatherForecast Map(DboWeatherForecast item)
        => new()
        {
            WeatherForecastId = new(item.WeatherForecastID),
            Date = DateOnly.FromDateTime(item.Date),
            Temperature = new(item.Temperature),
            Summary = item.Summary
        };

    public static DboWeatherForecast Map(DmoWeatherForecast item)
        => new()
        {
            WeatherForecastID = item.WeatherForecastId.Value,
            Date = item.Date.ToDateTime(TimeOnly.MinValue),
            Temperature = item.Temperature.TemperatureC,
            Summary = item.Summary
        };
}

您可以在此处查看完整的实现:https://github.com/ShaunCurtis/Blazr.Demo

以及简单的发票复杂对象实现。

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