【问题标题】:EF DB-first mapping messEF DB-first 映射混乱
【发布时间】:2015-08-09 05:45:14
【问题描述】:

由于 EF 的这个小怪癖,我遇到了令人沮丧的情况。这是该行为的简单演示。首先是数据库架构:

如您所见,RestrictedProduct 是产品的一个特例,我打算用一些特殊代码创建Product 的子类。

现在我导入到 EF 数据模型:

哎呀! EF 发现 RestrictedProduct 只有 2 个字段,都是 FK,因此它将其映射为 ProductRestriction 之间的一对多关系。于是我回到数据库,给RestrictedProduct添加了一个Dummy字段,现在我的EF模型看起来好多了:

但是 Dummy 字段既愚蠢又毫无意义。也许我可以删除它?我从数据库表和实体模型中吹掉字段,然后从数据库中刷新模型...

哦,不! Product-Restriction 协会以新名称 (RestrictedProduct1) 又回来了!另外,它不会编译:

错误 3034:从行 (x, y) 开始映射片段时出现问题:具有可能不同键的两个实体映射到同一行。确保这两个映射片段将 AssociationSet 的两端映射到相应的列。

除了将Dummy 字段保留在RestrictedProduct 表上之外,有什么方法可以防止这种行为?

【问题讨论】:

  • 尝试另一种方式,创建类模型并查看 EF Code First 在数据库中创建的表
  • @Wim - 好主意!我这样做了,生成的数据库模型与我开始使用的基本相同。但是从数据库中刷新并不会弄乱 EF 模型!看不到 EDMX 文件的底层 XML 之间有任何明显的区别,但那里有很多技术问题,我敢肯定其中一定有一些秘密开关。知道它可能是什么吗?
  • 没有,我帮不了你。如果您确实发现了什么,请告诉我们。
  • @Shaul 听起来你在这里有一个领域驱动的设计。您确定 DB first 是适合您的方法吗?我不认为 edmx 生成器可自定义以允许您关闭对某些关联的识别。
  • @bmewsing 我的印象是 DB-first 和 code-first 几乎可以互换,因为您应该从任何一种方法中获得几乎相同的结果。我弄错了吗?

标签: c# entity-framework entity-framework-5 database-first


【解决方案1】:

我刚刚遇到了同样的问题,作为将虚拟字段放入您的 RestrictedProduct 表中以强制创建实体的替代方法,您还可以使您的 RestrictedProduct.RestrictionId 字段可为空,然后 EF 将生成一个实体为了它。然后您可以修改它以使用继承,并且任何后续的“从数据库更新模型”都不会导致不需要的导航属性。不是一个很好的解决方案,而是一种解决方法。

【讨论】:

  • 如你所说,并不理想,因为它在概念上确实不可为空,但并不比虚拟字段差,所以无论如何 +1...
【解决方案2】:

让我们慢慢解决您的问题。

您需要决定的第一件事是受限制的产品是否是 真的是产品的特例还是可能的扩展 每个产品。

从您原来的数据库方案看来,任何产品都可能有 与单个限制的关系但是单个限制 可以在许多产品之间共享..所以这是一个简单的一对多 这种情况意味着受限产品不是特例 产品!限制是一个没有任何东西的独立实体 以特定方式处理产品。

因此,EF 在您的方案的第一次导入中是正确的: 1.一个产品可以有0个或1个限制。 2. 限制是可以与许多产品相关的另一个实体。

我没有看到你的问题。

【讨论】:

  • 感谢您的回答!我理解你为什么问这个问题,但我会转移它。我给出的案例不是我的实际架构,但是要解释我系统中的业务规则需要很长时间,而且这是题外话。假设RestrictedProduct确实是一种特殊的Product,具有不同的业务规则,类代码会覆盖Product中的一些虚方法。
  • 补充我之前的评论:想象一下你还有其他 Product 子类也有不同的业务规则。对我来说,只有一个额外字段(如RestrictionID)的那些将生成为关系,而那些有多个字段的将值得他们自己的类。
  • RestrictedProduct 以何种方式成为产品的子类?它带来了什么?您遇到的问题与面向对象设计有关-与 EF 无关,如果我们去经典的动物园示例:您有“动物”类和“访客”类,并且您想说因为可以访问一些动物,所以他们需要被分类..这是错误的!你可以在你的动物类上有一个属性 IsBeingVisited - 这将是正确的方法。您需要区分什么时候应该对 somthing 进行子分类,以及什么时候 somthing 只是另一个属性,因为基本规则会询问它是否添加了 somthing。
  • 我经历过这个过程。我理解子类和属性之间的区别。请把它当作一个给定的事实,确实有一个真正的业务需要有一个子类。
  • 好吧,在这种情况下,您需要对产品设置限制,因为它是您的 RestrictedProduct 的基类,并消除 RestrictedProduct Restriction 之间的关系...但我认为它不会再直观一点:)
猜你喜欢
  • 1970-01-01
  • 2018-02-17
  • 2018-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多