【问题标题】:Entity Framework 6 - Referencing Table - How to write custom naviagtion-property-logic?实体框架 6 - 参考表 - 如何编写自定义导航属性逻辑?
【发布时间】:2014-09-22 09:31:47
【问题描述】:

在不允许我们进行巨大更改的数据库中,在其他表格中,我们有以下表格(不相关的列隐藏在 [其他一些列...] 后面):

大师

Id, [some other columns...]

表 1

Id, [some other columns...]

表2

Id, [some other columns...]

参考文献

Id, MasterId, TableName, ForeignId

我们正在使用 EF6(代码优先,首选数据注释)来访问数据库。

现在我们希望能够在我们的代码中导航,例如通过“master.References.First().ReferenceRow”到引用的表。在这种情况下,“ReferenceRow”可能是一个导航属性,我们需要在“映射”后面放置一些额外的自定义逻辑,例如“看看值 TableName,如果 Table1 从 Table1 中取行where Id = ForeignId, else if Table2... " TableName 列类似于 TPH 中的鉴别器列。我认为 EF 中的 scanario 没有开箱即用的解决方案,但是是否可以将此逻辑添加到导航属性中?

当然,我们可以创建一个抽象类“RefereceTable”,让所有可以引用的表都继承它。但在这种情况下,TPH 会创建很多列。 TPC 和 TPT 不会给我们想要的性能。这就是为什么我们不能按原样使用这些继承类型来解决这个问题的原因。此外,该表的唯一公共列是 Id 列。

这就是我们想知道的原因:有没有办法在导航属性后面实现自定义逻辑来解决我们的问题?

【问题讨论】:

  • 这种逻辑不应该在导航属性中。它属于存储库层中的某个位置。所以像 GetReferencesByMasterId(int masterId) 这样的函数可以有代码来查看不同的导航属性..
  • @tranceporter 是的,没错,这就是我们的实际情况,可以阅读。但是对于插入我们有一些问题:假设我们要在 Master 中插入一行,在 Table1 中插入一行,在将其他行链接在一起的 References 中插入一行。在保存之前我们不知道 Table1-Row 的 Id,所以我们必须再次调用 SaveChanges() 来保存 References-row。这将导致第二次交易。面对这个问题,让我对上述问题产生了兴趣。
  • 看看我的回答有没有帮助。
  • 实体每张表都有一行吗?

标签: c# .net entity-framework entity-framework-6


【解决方案1】:

根据您的评论,您无需担心 Table1-Row 的 Id。 EF 将为您处理。您需要做的就是构建实体的层次结构并调用 SaveChanges 一次。

var master = _context.Master.Create();
master.property1 = "xyz";

var table1Row = _context.Table1.Create();
table1Row.property1 = "abc";

var referenceRow1 = _context.Reference.Create();
referenceRow1.MasterId = master.Id;
referenceRow.TableRow1Id = table1Row.Id;

_context.SaveChanges();

按照这些思路做的事情应该可以实现您想要实现的目标。

【讨论】:

  • 这似乎不起作用,因为 References.ForeignId 未声明为某个表的外键。它没有参考,因为我们无法在女巫桌上知道它会在设计时参考。设置 masterId 工作正常,但 ForeignId 的值为 0。还有其他想法吗?
  • 在这种情况下,与其拥有一个 ForeignId 列,我将拥有多个列,例如 Table1Id、Table2Id,并去掉 TableName 列。这样,您可以创建外键,然后在需要时对 Table1Id 和 Table2Id 设置检查约束。 (如 Table1Id 为 null && Table2Id 为 null 无效,可以通过检查约束进行捕获)。 IMO 这是一个更好的数据库设计,将确保更好的数据完整性。
  • 像这样更改数据库设计,对我们的应用程序来说可以正常工作。但是还有其他应用程序在使用该数据库,因此如果不对其他应用程序进行大量工作,这是不可能的。当然可以,但这不是我们想要的……抱歉……
猜你喜欢
  • 2022-01-16
  • 2020-11-21
  • 1970-01-01
  • 1970-01-01
  • 2014-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多