Mic*_*hel 10 c# entity-framework entity-framework-6
我们有一个基础对象,首先包含10个子对象和EF6代码.
在这10个子对象中,5个只有少数(额外)属性,5个具有多个属性(5到20个).我们将它实现为每个类型的表,因此我们有一个基表和1个子项(总共10个).
然而,这产生巨大的选择查询select case和unions所有的地方,这也需要在EF 6秒产生(第一次).
我读到了这个问题,并且在每个具体的表格类型场景中也存在相同的问题.
所以我们剩下的就是table-per-hierachy,但这会创建一个包含大量属性的表,这听起来也不是很好.
还有其他解决方案吗?
我想可能会跳过继承并创建一个联合视图,以便在我想从所有子对象/记录中获取所有项目时.
还有其他想法吗?
提前致谢.
另一种解决方案是实现某种CQRS模式,其中您有用于写入(命令)和读取(查询)的单独数据库.您甚至可以对读取数据库中的数据进行反规范化,因此速度非常快.
假设您需要至少一个具有参照完整性的规范化模型,我认为您的决定实际上归结为每个层次的表和每个类型的表.来自EF团队的Alex James以及最近在微软数据开发网站上报告的 TPH 表现更好.
TPT的优点以及为什么它们不像性能那么重要:
更大的灵活性,这意味着能够在不影响任何现有表的情况下添加类型.没有太多关注,因为EF迁移使生成所需的SQL以更新现有数据库而不影响数据变得微不足道.
由于具有较少的可空字段而进行数据库验证.由于EF根据应用程序模型验证数据,因此不是一个大问题.如果通过其他方式添加数据,则运行后台脚本来验证数据并不困难.此外,TPT和TPC实际上在主键验证方面更糟糕,因为两个子类表可能包含相同的主键.通过其他方式留下验证问题.
由于不需要存储所有空字段,因此减少了存储空间.这只是一个非常微不足道的问题,特别是如果DBMS有一个很好的策略来处理'稀疏'列.
设计和肠道感觉.拥有一个非常大的表确实感觉有点不对劲,但这可能是因为大多数数据库设计人员花了很多时间来规范数据和绘制ERD.拥有一个大表似乎违背了数据库设计的基本原则.这可能是TPH的最大障碍.请参阅此文章以获得特别激动人心的论点.
该文总结了针对TPH的核心论点:
它甚至在一个微不足道的意义上也没有被标准化,它使得不可能对数据实施完整性,并且最"令人敬畏的是:"它几乎可以保证在任何非平凡的数据集中大规模地执行.
这些大多是错的.上面提到了性能和完整性,TPH并不一定意味着非规范化.只有许多(可空)外键列是自引用的.因此,我们可以像使用TPH一样继续设计和标准化数据.在当前数据库中,我在子类型之间有许多关系,并创建了一个ERD,就像它是TPT继承结构一样.这实际上反映了代码优先实体框架中的实现.例如,这是我的Expenditure类,Relationship它继承自Content:
public class Expenditure : Relationship
{
/// <summary>
/// Inherits from Content: Id, Handle, Description, Parent (is context of expenditure and usually
/// a Project)
/// Inherits from Relationship: Source (the Principal), SourceId, Target (the Supplier), TargetId,
///
/// </summary>
[Required, InverseProperty("Expenditures"), ForeignKey("ProductId")]
public Product Product { get; set; }
public Guid ProductId { get; set; }
public string Unit { get; set; }
public double Qty { get; set; }
public string Currency { get; set; }
public double TotalCost { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
在InversePropertyAttribute和ForeignKeyAttribute提供EF与尽在单个数据库所需的自加入所需的信息.
Product类型也映射到同一个表(也继承自Content).每个产品在表中都有自己的行,包含支出的行将包含ProductId列中的数据,对于包含所有其他类型的行,该数据为空.因此数据被标准化,只放在一个表中.
首先使用EF代码的好处是我们以完全相同的方式设计数据库,无论使用TPH还是TPT,我们都以(几乎)完全相同的方式实现它.要将实现从TPH更改为TPT,我们只需要为每个子类添加一个注释,将它们映射到新表.所以,对你来说好消息是你选择哪一个并不重要.只需构建它,生成一堆测试数据,测试它,改变策略,再次测试它.我估计你会发现TPH是胜利者.
| 归档时间: |
|
| 查看次数: |
3178 次 |
| 最近记录: |