3

我们使用在 Len Silverston 的 Data Model Resource Book Vol. 中找到的两种模式在 SQL Server 中构建了一个数据库。3,一个用于类型和类别:分类,另一个用于层次结构、聚合和对等关系。本质上,它的实现如下:

分类

[实体] (M x M) [EntityType] (M x M) [EntityTypeType]

...其中 (M x M) 是由分类表在数据库中实现的多对多关系。

协会

上面的实体和类型表也有自己的类型汇总:

  • [实体] (M x M) [实体]
  • [实体类型] (M x M) [实体类型]
  • [EntityTypeType] (M x M) [EntityTypeType]

...其中每个 (M x M) 是在汇总表中实现的多对多关系,具有汇总/关联类型的外键。

由此产生的数据结构在描述我们的实体及其相互关系方面为我们提供了巨大的表达能力。但是,我们在应用程序中利用这种表现力时遇到了麻烦。主要问题是,尽管 EF 4 和 5 取得了进步,但 M-2-M 关系仍然很棘手,而且每当我们访问数据库时,我们都会尝试在至少 2 个方向上访问 M-2-M。尤其复杂的是:

  1. 我们对 [Entity] 和 [Entity] 的一些子类型进行子类型化。
  2. 所有 M2M 表 - 所有分类和汇总/关联表 - 都有一个有效负载,其中至少包含一个 From 和 Thru 日期。汇总还包含至少一个汇总类型。
  3. 我们不希望每次访问实体时都为了在运行时解释数据而加载输入模式的大而遥远的部分(EntityTypeType 表及其汇总)。

技术

  • SQL Server 2008 R2
  • 实体框架 5
  • .NET 4.5
  • MVC 4(在网络应用部分,我们也有一些控制台应用)

关于模型本身的问题:

  • 这仅仅是 .NET 中不可行的数据模型吗?
  • 我们是否应该首先将我们的数据库扁平化为对我们的业务对象进行建模的对 .NET 更友好的视图?

关于打字方案的问题- 请记住,类型是相当静态的:

  • 我们是否应该将 [EntityType] 和 [EntityTypeType] 表、它们的分类以及它们汇总到 C# 类中?这将类似于枚举脚手架,只是我们需要的不仅仅是名称/int,因为它们具有有效负载日期范围和类型有效负载。如果是这样,对于如何将这些文件构建为静态类的一些想法是什么?硬编码的对象列表?
  • 我们是否应该在启动时缓存打字方案(这让我很困扰,因为它增加了启动控制台应用程序的大量开销)?
  • 任何其他想法 - 脚手架 XML 文件?ETC...

非常感谢任何想法或经验!

4

2 回答 2

2

我试图回答每个问题,但我不得不承认我不确定您是否尝试在运行时在数据库之上动态创建实体 - 或者您是否只是尝试在运行时动态创建实体.

如果您尝试发布在 SQL Server 中的架构更改时动态更改/调整的代码,那么我会有一些不同的答案。=)

这仅仅是 .NET 中不可行的数据模型吗?

你提到的一些让我印象深刻的事情:

  1. 很多 M x M 关系。
  2. 实体/实体类型/实体类型类型
  3. 汇总

我阅读后的一些问题:

  1. 你们是否选择了一个数据建模框架,希望它能让一切变得更容易?
  2. 你选择一个框架是因为它看起来是“正确”的方式吗?
  3. 我很难理解你是如何对数据建模的。EntityTypeType 到底是什么?
  4. 真的需要所有 M x M 关系吗?仅仅因为实体 A 和实体 B 可以处于 M x M 关系,他们应该吗?

我不知道您的域名,但我知道我很难按照您的描述进行操作。=)在我看来,它已经变得有些不可行,原因有两个:1)你在问这个问题,b)没有很多文字就不容易描述。

我们是否应该首先将我们的数据库扁平化为对我们的业务对象进行建模的对 .NET 更友好的视图?

是的!

至少根据我的经验,我会说是的。=)

我认为可以在数据库中创建具有复杂关系的实体。父/子、点对点、分层等。一切都很好,很正常。

但是应用程序不应该解释所有这些来理解它。该数据库擅长连接、分组数据、创建视图等。我建议创建尽可能接近您的业务对象的视图或存储过程 - 至少对于读取而言。

还要考虑到,如果您将关联对象的复杂性推到应用程序中,您可能会付出一些性能损失。

我们是否应该将 [EntityType] 和 [EntityTypeType] 表、它们的分类以及它们汇总到 C# 类中?

我建议不要这样做。唯一的原因是你现在在应用层做数据库工作。如果你想做加入/汇总/等。您在应用程序中管理该数据 - 而不是数据库。

我确定您已经知道这一点,但您希望避免将数据库中的所有内容带回应用程序,然后运行查询/构建对象。

SQL Server 非常擅长关联对象并将不同的实体组合在一起。在那个层它会非常快。

我将创建业务对象并从 SQL 填充这些对象。

如果您需要构建 EntityType/EntityTypeType,请注意不要遇到 N+1 问题。

关于如何将这些文件搭建为静态类的一些想法是什么?硬编码的对象列表?

选项:

  1. 使用 ORM 为您生成类。您已经在 EF 中看到了其中的一些内容。
  2. 通过查看实体的 SQL Server 架构来编写您自己的代码生成工具。
  3. 手动编写未生成的类。我一直看到这样做,它并没有你想象的那么糟糕。绝对是一些繁重的工作,但也提供了灵活性。
我们是否应该在启动时缓存打字方案(这让我很困扰,因为它增加了启动控制台应用程序的大量开销)?

您想在应用程序加载时根据您的实体生成业务对象吗?或者另一种表达问题的方式......在运行时生成代理类?

于 2013-03-04T18:02:12.097 回答
1

我不熟悉 Len Silverston 的书,而且我认为绝大多数 StackOverflow 用户也不熟悉。由于您在 3 天内没有得到问题的答案,我现在无论如何都会对此发表评论。

在您的数据库模型中让我感到奇怪的是,您似乎有多个嵌套的 N:M 关系。很少有真正的 N:M 关系 - 大多数时候 N:M 关系模型中的中间表实际上代表了现实生活中存在的对象,给您留下两个常规的 1:N 关系,并且不仅仅是两列链接表。在过去的 25 年中,我只遇到过一两个真正的 N:M 关系,所以我有点怀疑你实际上在这里有三个 - 看起来你使用的模式更有可能不适用于你认为的方式。

你描述的东西有点像你试图在数据库中建模一个数据库。尤其是“我们是否应该首先将我们的数据库扁平化为对我们的业务对象进行建模的对 .NET 更友好的视图?” 听起来很可疑。除了极少数例外,您的数据库表应该从一开始就与您的业务对象匹配。如果您需要创建一个平面视图来查看您的实际对象,那么您可能完全朝着错误的方向前进。但是话又说回来,很难从您提供的信息中分辨出来。

请对您正在尝试做的事情、到目前为止所做的事情做一个不那么抽象的描述。

于 2013-03-01T12:41:58.660 回答