假设我有一个包含以下项目的.NET Core / C#解决方案:
MyProject.Application1
/ Application2
/ etc:这些是实际的应用程序。它们可能是ASP.NET Core Web API或控制台应用程序,但它们都使用DI,并且它们引用了其他项目MyProject.Services
:包含随后在应用程序中使用的服务的库MyProject.Data
:它包含用于使用NoSQL数据库的数据库存储库和实体(POCO类)。此处不使用实体框架我的问题是:
在MyProject.Data
项目中,我有数据库实体,它们是简单的类,具有将属性映射到数据库列的属性。如果我拥有ASP.NET Core Web API,可以直接将这些实体用作控制器的返回类型吗?更笼统地说,是否可以在应用程序周围重用这些实体,甚至可以直接使用new
创建对象?
此外,如果我必须将这些实体序列化为JSON,则可能需要向其属性添加一些属性。但是,那时我将拥有同时具有数据库和序列化世界属性的类。这对我来说听起来并不好,似乎我没有保持正确的分隔。有替代方案吗?继承或合成模式在这里有用吗?
如果我有与数据库无关但在整个应用程序中都使用过的其他实体(模型?),我应该将这些类放在MyProject.Data
(或也许{{1 }})项目?还是应该为他们创建类似.Services
或MyProject.Domain
的项目?在这一点上,也许我也应该在另一个项目中分开数据库实体?
谢谢。
答案 0 :(得分:2)
实体类本身只是DTO;它们是将数据从数据库传输到应用程序层的一种方式。但是,正如您已经正确指出的那样,存在一个关注点分离的问题。由于实体的主要目的是服务于数据库,因此几乎总是不适合服务于其他事物,例如请求/响应主体,视图等。如果类型非常简单,则可能不必使用其他类型,但是在大多数情况下,您将需要DTO /视图模型。
序列化是一个特殊的用例,几乎总是需要一个单独的类型。特别是在您的实体使用任何导航属性的情况下。一般地对实体进行序列化通常会导致获得比序列化所需的数据更多的数据,在最坏的情况下,甚至可能由于循环到嵌套深度太深的引用而导致失败。拥有专用的DTO类进行序列化,您可以显式地对所需的JSON对象进行建模,然后用您的实体中的对象选择性地填充它。
通常来说,您的DTO应该位于它们所服务的层中。因此,例如,如果您有一个实体Foo
,然后是一个用于API应用程序的DTO FooResource
,则Foo
将位于您的数据层,而FooResource
将在您的API应用程序中。您的API将依赖于您的数据层,并且还将包含有关如何将Foo
映射到FooResource
或从$ ng new myapp
$ cd myapp
映射的逻辑。