Jas*_*n H 5 c# enums entity-framework
我曾在很多商店工作,他们运行数据库优先模型,因此总是需要查找表.您的查找表必须与您的枚举匹配,以便保持数据库的完整性.我100%同意这个想法,但已经发现,当涉及到Code First Model时,这不是开箱即用的.我确实在某处读过EF团队可能会添加在EF7中动态地将Enums添加到您的数据库(通过迁移)的功能,但他们警告说这不是承诺.
那么你(如果有的话)如何实现这一目标呢?我将在下面的答案中提供我的解决方案,并期待您的反馈.
我使用的是EF 6.1.3和.NET 4.5.1
所以我不会撒谎,我的解决方案有点深入,但我过去几天一直在使用它,我发现它的工作方式正如我所需要的那样.
让我们从顶部开始,我创建的基类:
public abstract class LookupTableBase
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
[Required]
public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这是我的一个查找表实体模型的示例:
/// <summary>
/// Lookup Table for Enumeration AddressTypes
/// File Reference: DataAccessLayer/Enumerations/Locators.cs
/// DO NOT USE
/// SHOULD NOT BE AVAILABLE IN ENTITY MODELS
/// </summary>
[Table("AddressTypes", Schema = "Lookup")]
public class AddressType : LookupTableBase {}
Run Code Online (Sandbox Code Playgroud)
以下是与此查找表一起使用的枚举:
public enum AddressTypes
{
[StringValue("")]
Unknown = 0,
[StringValue("Home")]
Home = 1,
[StringValue("Mailing")]
Mailing = 2,
[StringValue("Business")]
Business = 3
}
Run Code Online (Sandbox Code Playgroud)
StringValue属性是我创建的自定义属性(基于我在网上找到的示例),允许我调用:
AddressTypes.Home.GetStringValue();
Run Code Online (Sandbox Code Playgroud)
这将返回字符串值:Home.
我将查找实体模型添加到我的DbSets中,因此将创建表,但我从未在任何其他实体模型中直接引用查找实体模型.它的唯一目的是在DB中创建查找表,以便我可以针对它们创建外键约束.
public DbSet<AddressType> AddressTypes { get; set; }
Run Code Online (Sandbox Code Playgroud)
在我的Context的OnModelCreating方法中,我确实必须添加它,因为Data Annotation似乎没有完全保留:
modelBuilder.Entity<AddressType>()
.Property(x => x.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
Run Code Online (Sandbox Code Playgroud)
在我的Migration的配置文件中,我将其添加到种子方法中:
var addressTypeCount = Enum.GetValues(typeof (AddressTypes)).Length;
var addressTypes = new List<AddressType>();
for (var i = 1; i < addressTypeCount; i++) {
addressTypes.Add(new AddressType {
Id = i,
Name = ((AddressTypes)i).GetStringValue()
});
}
context.AddressTypes.AddOrUpdate(c => c.Id, addressTypes.ToArray());
context.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
最后,在Migration文件本身中,我将所有查找表创建方法移到列表顶部,现在我可以将外键约束添加到引用该枚举的任何表中.就我而言,我更进了一步.由于Migration Class是部分的,我创建了另一个部分类来匹配它.创建了两种方法:
public void LookupDataUp()
public void LookupDataDown()
Run Code Online (Sandbox Code Playgroud)
在LookupDataUp方法中,我添加了所有自定义外键和索引,并在LookupDataDown中删除了所有自定义外键和索引.
当我运行Update-Database时,我以前的所有表都有一些表示某些东西的整数值(在这种情况下是一个AddressType)但没有实际值,现在有一个值可以通过将它链接到它的查找表来看到.
我承认,这似乎只是为了将少量数据存入数据库,但现在每次我删除/更改/添加新项目到我的枚举时,它都会自动推送到数据库.正如我在上面的问题中所述,这通过在"整数"字段上具有外键约束来创建数据库完整性.
| 归档时间: |
|
| 查看次数: |
7918 次 |
| 最近记录: |