mysql - Enity Framework Core:处理大量类似枚举的字段
问题描述
我目前面临以下问题:我有一个LargeDataClass
包含许多字段(200+)的模型类。其中许多字段(约 50-80)类似于枚举(即它们可以用 UI 中的某些选项集填写)。现在我的方法是将这些建模为枚举类,比如
[Table("tbl_enum_one")]
class EnumOne {
public int ID { get; set; }
public string Name { get; set; }
}
[Table("tbl_large_dataclass")]
class LargeDataClass {
public EnumOne EnumOne { get; set; }
public int EnumOneId { get; set; }
//...
}
这具有易于扩展的主要优点(要在 UI 中添加下拉选项,只需向表中添加一行)。现在我面临一些担忧/问题:
- 当我从包含所有枚举字段的数据库中获取我的模型类
LargeDataClass
时,将会有很多连接(如上所述,这些字段中有 50 到 80 个)。我担心这会对查询性能产生很大影响。另外,由于要更新大量索引,创建/更新/删除可能会很慢。 - MySQL 甚至不会让我创建
tbl_large_dataclass
具有那么多 FK 的表(单个表上的索引太多)。
所以现在我正在考虑两个(在我看来真的很不幸)选项:
使用常规枚举,因此没有枚举类具有自己的表,将它们作为简单的 int/string 字段存储在数据库中。这根本不会引起性能问题,但不幸的是,“实时”可扩展性非常重要,所以这个选项只是最后的手段。
使用 Enum 类,但在 中只有枚举的 ID
LargeDataClass
,因此保留了这是来自数据库的外键机密的事实。如果我想在LargeDataClass
某处显示一个对象,我将不得不单独获取枚举类。另外,我必须特别确保我只使用枚举表中真正存在的 Id。
我真的不确定这里最好的方法是什么。
解决方案
数据库不是对象存储,您必须相应地设计它。我已经改变了你的架构,只需要两个表来存储下拉值。
[Table("tbl_enum_type")]
public class EnumType {
public int ID { get; set; } // PK
public string Name { get; set; }
}
// PK (EnumTypeId, Id) - reusing the same index for dropdown generation
[Table("tbl_enum_value")]
public class EnumValue {
public int ID { get; set; }
public string Name { get; set; }
public int Order { get; set; } // for dropdown ordering
public int EnumTypeId { get; set; }
public EnumType EnumType { get; set; }
}
// store only ID's, no FK
[Table("tbl_large_dataclass")]
public class LargeDataClass {
public int EnumOneId { get; set; } // EnumTypeId 1
public int EnumSecondId { get; set; } // EnumTypeId 2
//...
}
为了生成下拉列表,您必须以有用的结构将 EnumType 和 EnumValue 表缓存在内存中。
覆盖方法SaveChanges/SaveChangesAsync
并根据缓存数据检查保存的 Id。
如果您的数据库是通过 SQL 更改的,这将无济于事,但在这里我们需要在性能和一致性之间进行权衡。可能好的触发器在这里可能会有所帮助。
更新:
考虑将 LargeDataClass 重构为两个表
[Table("tbl_option_bag")]
public class OptionBag {
public int Id { get; set; }
public ICollection<Option> Options { get; set; }
}
[Table("tbl_options")]
public class Option {
public int Id { get; set; }
public int OptionBagId {get; set; }
public int EnumTypeId { get; set; }
public int EnumId { get; set; }
//...
}
在这里,您可以使用 FK,并且可以在选择 Options 导航属性时生成 DTO。
推荐阅读
- coordinates - X,Y 坐标与参考点并找到纬度和经度
- visual-studio-code - 在 Visual Studio Code 中搜索包含任何内容的字符串
- javascript - 如何为电子中的文件制作自定义网址
- mysql - 如何在节点js中获取带有图像的ckeditor4的内容
- javascript - 获取没有兄弟元素的集合分支,按属性搜索
- javascript - 如何在 webpack 中的 bundle 之间摇树依赖关系?
- sockets - 读取内容或获取 ssl_write() 写入的缓冲区大小
- crystal-reports - Crystal Reports ODBC 在 CMC 中不起作用
- tailwind-css - Tailwind - 链接在悬停时没有默认光标指针
- wordpress - 编辑优雅杂志主题的页脚