是否可以使用子类使用EF Core实现关注点分离? [英] It is possible to use child class to implement Separation of concerns using EF Core?

查看:74
本文介绍了是否可以使用子类使用EF Core实现关注点分离?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标是使用DBContext异步加载相关实体.

My goal is async loading of related entities using DBContext.

让我们想象两个项目.第一个名为 MyApp.Domain ,并包含域实体.

Let imagine two projects. The first named MyApp.Domain and contains domain entities.

namespace MyApp.Domain
{
    public class PlanPage
    {
        public Guid Id { get; set; }
    }
}

namespace MyApp.Domain
{
    public class PlanPageDay
    {
        public Guid Id { get; set; }
        public Guid PlanPageId { get; set; }
    }
}

第二个项目名为 MyApp.Infrastructure.EntityFramework ,其中包含对数据库的投影实体的配置.它还包含扩展领域实体并实现实体框架特定逻辑的类.

The second project named MyApp.Infrastructure.EntityFramework and contains configuration of projection entities to database. It also contains class which extends domain entity and implements Entity framework specific logic.

namespace MyApp.Infrastructure.EntityFramework.Models
{
    public class PlanPageEntity : PlanPage
    {
        private readonly ApplicationDbContext _applicationDbContext;

        protected PlanPageEntity(ApplicationDbContext applicationDbContext)
        {
            _applicationDbContext = applicationDbContext;
        }

        public ICollection<PlanPageDay>? Days { get; set; }

        public async Task<ICollection<PlanPageDay>> GetDays()
        {
            return Days ??= await _applicationDbContext.PlanPageDays
                .Where(pd => pd.PlanPageId == Id)
                .ToListAsync();
        }
    }
}

此示例的目的很简单.我们将基础结构代码与域代码分开.看看我们打算如何使用这个概念:

The purpose of this example is simple. We separate infrastructure code from domain code. Look how do we plan to use this concept:

// Entity initializing code. Placing somewhere in domain logic.
var plan = new PlanPage(/*some constructor arguments*/);

// Entity loading code. Placing somewhere in infrastructure implementation.
public async Task<PlanPage> GetPlanPage(Guid id)
{
    return await _applicationDbContext.Set<PlanPageEntity>().FindAsync(id);
}

请注意,我们告诉Entity框架使用子类( PlanPageEntity ),以便它可以处理所有可以处理的特定事情.

Note that we tell to Entity framework to use child class (PlanPageEntity) so it can handle all specific things that it can.

问题是:是否可以配置EF以使我们能够使用此概念?

The question is: Is it possible to configure the EF so that it allows us to use this concept?

推荐答案

根据要求,我在评论中提供了一些更详细的意见.

As requested here's a little more details for my opinion stated in the comments.

我认为您当前的方法是一个坏主意的主要原因是,它违反了关注点分离设计原则:在将域模型与数据访问模型混合使用时,域逻辑完全取决于在数据库中对数据进行建模的方式.这很快就限制了您的选择,因为数据库在如何建模数据方面可能存在一些限制,这些模型与您要实现的域逻辑不太吻合,并且使维护变得困难.例如.如果您决定将一个数据库表拆分为两个表,那么您可能要完成一项艰巨的任务,以使您的域逻辑能够与这两个新模型/表一起使用.此外,如果不提前考虑,在数据库中进行性能优化就容易成为噩梦-而且,您不应该花时间思考优化系统的必要性.

The main reason why I think your current approach is a bad idea is that it violates the separation of concerns design principle: when you are mixing domain models with data access models, you make your domain logic completely dependent on how you model the data in your database. This quickly limits your options because the database may have some restrictions on how you can model your data that doesn't fit well with the domain logic you want to implement as well as making maintenance difficult. E.g. if you decide to split up one DB table into two then you might have a big task ahead of you in order to make your domain logic work with those two new models/tables. Additionally, making performance optimizations in your database easily becomes a nightmare if not thought through ahead of time - and you shouldn't spend time thinking of optimizing your system before it's necessary.

我知道这有点抽象,因为我对您的域名不太了解,但是我敢肯定我会发现更多反对它的论点.

I know this is a little abstract since I don't know much about your domain but I'm sure I could find more arguments against it.

相反,将数据访问模型(通常是所有外部数据模型)与域模型分开可以更轻松地维护:如果您需要对数据库进行一些更改,则只需要更新映射数据库的逻辑即可.从数据访问模型到域模型的数据-域逻辑中的任何内容都无需更改.

Instead, separating data access models (and in general all external data models) from your domain models makes it much easier to maintain: if you need to make some changes to your database, you simply need to update the logic that maps the data from your data access models to your domain model - nothing in your domain logic needs to change.

在给出的示例中,您已经在逻辑上将域模型和数据访问模型分离到了两个单独的项目中.那么,为什么不遵循这种想法,并在两者之间使用绑定/映射层将两者分开呢?

In the examples you have given, you have already logically separated your domain models and data access models into two separate projects. So why not follow through with that thought and separate the two with a binding/mapping layer in-between?

这篇关于是否可以使用子类使用EF Core实现关注点分离?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆