代码优先映射和存储库

时间:2017-12-05 02:43:40

标签: vb.net entity-framework class design-patterns

我正在学习存储库模式和实体框架。我有一个关于如何使用EF 6 Code First(现有Db)映射我的类的问题。我知道有很多关于这个问题的问题(而且我已经把它们搞砸了)但是我仍然很难理解某些东西,这似乎是“逻辑”但它让我发疯(也许我已经引起了太多不同的意见) ...)

问题(示例)

Processes,它存储不同的流程,如要约,收据,订单等。表格的一列是AddDate,表示此流程何时添加到数据库。

现在我想编写一个库来访问这个数据库,以便在不同的应用程序中使用它,因为它是公司的核心 Db。

在库中,我希望公开一个ProcessRepository,其方法为GetByAddDateRange,它返回在给定时间范围之后,之前或之中添加的进程。

问题

所以,现在使用CodeFirst到现有数据库的EF首先为每个表生成一个类,每个表都有一个属性。所以我有一个课程Process(从现在开始ProcessEntity),其中包含一个属性AddDate

现在在我的“域模型”中,我想要在我的业务逻辑等中使用的类,我希望有一个类Process(从现在开始ProcessDomain)但是这不应该有{ {1}}属性,因为它对“对象”不重要或者是“属性”的一部分。

那么现在如果我想使用此AddDate作为条件从我的AddDate获取ProcessDomains,我该怎么办?

  1. 如果我直接使用ProcessRepository作为“域模型”(由EF生成的类),如果我理解正确,我必须有一个名为ProcessEntity的属性,因为我需要它在我的回购时,做某事如AddDate还是没有?

  2. 我可以(就像我读过的那样)有一个类Return _dbContext.Set(Of Process).Where(Func(s)s.AddDate>addDate)ProcessEntity,并在我的存储库中手动映射它们。如果我理解正确,repo应该返回上面层的预期类型,在这种情况下应该返回我的domainModel类。

  3. 我理解吗?

    所以对我来说,第一个选项似乎只是在所有场景中都没用,因为你必须在你的类中拥有特定的属性。因此,无论我如何尝试查看问题,我总是看到在使用现有数据库时需要手动映射。

    也许我错过了某事或理解错误,所以请告诉我。

2 个答案:

答案 0 :(得分:1)

您的EF实体需要拥有您要使用的所有数据库列的属性,其中包括您要过滤的那些列。这意味着与该表对应的EF类必须具有该AddDate属性。如果你想要一个没有该属性的类,那么你需要定义另一个类。

无论如何,许多开发人员/团队都会这样做。我们在办公室里主要做ASP.NET MVC工作,我们有一个EF模型,它对应于从中返回类型的数据库和存储库,然后我们有一个服务层将这些EF实体映射到数据传输对象(DTO)。 DTO可以100%映射到相应的实体,但是它们也可能缺少一些属性和/或具有额外的属性。可能还存在与单个实体不对应的DTO。我们通常在应用程序和数据库之间使用Web服务,因此DTO与减少数据传输的效率一样高。

我们有自己的工具来生成基于EF模型的DTO。然后,我们将根据需要调整生成的代码。如果我们需要添加成员,我们通常在部分类中这样做,因此将来的重新生成不会影响该代码。如果我们需要删除成员,那么我们别无选择,只能编辑生成的代码。我们还使用AutoMapper在EF实体和DTO之间映射数据,反之亦然。

答案 1 :(得分:1)

选项1:

创建具有您真正想要的DTO。读/写时实体和DTO之间的映射。 (映射很繁琐且容易出错.AutoMapper有很多帮助。)

选项2:

在实体上使用DataContract / DataMember等属性来控制序列化哪些字段以及忽略哪些字段。

仍然容易出错,因为实体中充满了不必填充的集合。

选项3:

使用其他ORM。 Tortuga Chain专为与DTO和ViewModels配合使用而设计,无需将其映射到实体。

https://docevaad.github.io/Chain/Introduction.htm