代码首先枚举投入查找表 [英] Code First Enumerations put into Lookup Tables
问题描述
我在很多商店,他们跑了数据库的第一个模型,以便查找表总是需要工作过。您的查找表了,让你保持数据库的完整性,以配合您的枚举。我100%这个想法同意,但已经发现,当它涉及到守则第一种模式,这不是现成可用的。我读的地方,在EF团队可能会增加在EF7动态已枚举添加到您的数据库的能力(通过迁移),但他们警告说,这不是一个承诺。
I have worked in a lot of shops where they ran a Database First Model so Lookup Tables were always required. Your lookup table had to match your Enums so that you kept database integrity. I 100% agree with this idea, but have found that when it comes to the Code First Model, this is not available out of the box. I did read somewhere that the EF Team may be adding the ability to dynamically have Enums added to your DB (via migrations) in EF7 but they warned that it's not a promise.
那么,你如何(如果有的话)做到这一点?我将提供下一个答案我的解决方案,并期待着您的反馈。
So how do you (if at all) accomplish this? I am going to provide my solution below in an answer and look forward to your feedback.
我使用EF 6.1.3和4.5.1的.NET
I am using EF 6.1.3 and .NET 4.5.1
推荐答案
所以,我不会说谎,我的解决方案是有点深入的,但我一直在使用它了,现在在过去的几天,我觉得它的工作原理正是我需要它。
So I am not going to lie, my solution is a bit in-depth but I have been using it now for the past few days and I find it works exactly as I need it to.
让我们从顶部开始,我的基类,我创建:
Let's start at the top, my base class I created:
public abstract class LookupTableBase {
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
[Required]
public string Name { get; set; }
}
下面是我的查找表的实体模型的一个例子:
Here is an example of one of my lookup table Entity Models:
/// <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 {}
下面是与此查找表云枚举:
Here is the Enum that goes with this Lookup Table:
public enum AddressTypes {
[StringValue("")]
Unknown = 0,
[StringValue("Home")]
Home = 1,
[StringValue("Mailing")]
Mailing = 2,
[StringValue("Business")]
Business = 3
}
的
的StringValue属性是一个自定义属性我创建(基于例子我在网上找到),允许我这样称呼:
The StringValue Attribute is a custom attribute I created (based on examples I found online) that allow me to call:
AddressTypes.Home.GetStringValue();
将返回家。
Which will return "Home".
我在查找实体模型添加到我的DbSets这样的表将被创建,但我从来没有直接引用查找实体模型中的任何我的其他实体模型。其唯一目的是在数据库中创建的查找表,这样我可以创建针对他们的外键约束
I add the Lookup Entity Model to my DbSets so the table will be created but I never directly reference the Lookup Entity Models in any of my other Entity Models. Its sole purpose is to create lookup tables in the DB so that I can create Foreign Key Constraints against them.
public DbSet<AddressType> AddressTypes { get; set; }
在我的上下文我OnModelCreating方法,我没有要补充这一点,因为数据注解没有似乎通过举办所有的方式:
In my OnModelCreating Method for my Context, I did have to add this because the Data Annotation did not seem to hold all the way through:
modelBuilder.Entity<AddressType>()
.Property(x => x.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
在我移民的配置文件,我加入到种方法如下:
In my Migration's Configuration file, I add this into the Seed Method:
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();
最后,在迁移文件本身我把所有的查找表的创建方法,以列表的顶部现在我可以添加外键约束来引用该枚举任何表。就我而言,我把它一步。由于移民类是局部的,我创建了另一个部分类来匹配它。创建了两个方法:
Last, in the Migration file itself I move all the lookup table creation methods to the top of the list, now I can add Foreign Key Constraints to any table that references that enum. In my case, I took it one step further. Since the Migration Class is a partial, I created another partial class to match it. Created two methods:
public void LookupDataUp()
public void LookupDataDown()
在LookupDataUp方法,添加我所有的自定义外键和索引,并在LookupDataDown删除我所有的自定义外键和索引。
In the LookupDataUp method, I add all my custom Foreign Keys and Indexes and in the LookupDataDown I Remove all my custom Foreign Keys and Indexes.
当我运行更新的数据库,我的表是曾经有代表的东西(在这种情况下的AddressType)一些整数值,但没有真正的价值,现在有一个值,可以通过它链接到它的查找表中可以看出。
When I run Update-Database, all my tables that used to have some integer value that represented something (in this case an AddressType) but had no real value, now have a value that can be seen by linking it to its lookup table.
我承认,这似乎是一个大量的工作只是为了得到一些数据量小到数据库但现在我每次删除/改变时间/增加新的项目,我的枚举,它会自动推到DB。另外我在上面的问题说明,本所具有的'整'字段的外键约束创建数据库的完整性。
I will admit, this seems like a lot of work just to get some small amount of data into the database but now every time I remove/change/add new items to my enum, it's automatically pushed to the DB. Plus as I stated in the above question, this creates database integrity by having the foreign key constraint on the 'integer' field.
这篇关于代码首先枚举投入查找表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!