c# - 如何在 Code First 中使用表值作为枚举?
问题描述
我有一张桌子,上面有先生、小姐、夫人、女士、博士等头衔
如果我使用 Code First 方法,如何将这些值用作枚举?特别是如果我想让它们在表格和 Code First 之间保持同步?
背景:我通过首先创建数据库然后使用 ADO .Net 实体数据模型来生成 Code First 模板进行反向工程,我可以将其用作指南,但不使用 Edmx 文件。
我看到一些带有 EDMX 文件的文章,但不是以这种方式?
解决方案
您可以创建一个 T4 模板(以下首先使用 Entity Framework 6 代码完成)。按照以下说明操作后,如果数据更改,则重新运行 T4。
以下GitHub 存储库中的完整源代码。
- 添加一个名为 PersonTitle.ttinclude 的新文件。
- 设置
Custom tool
为TextTemplatingFileGenerator
- 更改
connectionString
为您的数据库连接字符串 - 在下面的示例中,我有三列,
Id
主键,Title
用于先生,小姐,例如 columnDescription
用于描述(这当然是可选的,但如果不存在,则将其从 select 语句中删除。
完成后,保存文件,您应该会收到一个提示,要求您继续,接受它。此时 Visual Studio 运行代码。如果有问题,它们将显示在“输出”窗口中。
如果没有问题,您将获得如下图 2 所示的输出。
新建一个文件,名称为PersonTitles.cs,复制图2中的代码,调整为图3。
作为演示,由于我没有准备好表/模型,以下摘自我的 Microsoft TechNet 文章Entity Framework database/Code First Enum support。CategoriesName是一个枚举。
public List<Product> GetProducts(CategoriesName categoriesName)
{
using (var context = new NorthWindContext())
{
return context.Products
.Where(prod => prod.CategoryID == categoriesName)
.OrderBy(p => p.ProductName)
.ToList();
}
}
图1
<#@ template debug="true" hostSpecific="true" #>
<#@ output extension=".cs" #>
<#@ Assembly Name="EnvDTE.dll" #>
<#@ Assembly Name="System.Data" #>
<#@ import namespace="EnvDTE" #>
<#@ import namespace="System.Data" #>
<#@ import namespace="System.Data.SqlClient" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Text.RegularExpressions" #>
<#
var tableName = Path.GetFileNameWithoutExtension(Host.TemplateFile);
var path = Path.GetDirectoryName(Host.TemplateFile);
var columnId = "Id";
var columnName = "Title";
var columnDescription = "columnDescription";
var connectionString = "data source=.\\SQLEXPRESS;initial catalog=NorthWindAzureForInserts;integrated security=SSPI";
// Get containing project
IServiceProvider serviceProvider = (IServiceProvider)Host;
DTE dte = (DTE)serviceProvider.GetService(typeof(DTE));
Project project = dte.Solution.FindProjectItem(Host.TemplateFile).ContainingProject;
#>
using System;
using System.CodeDom.Compiler;
namespace <#= project.Properties.Item("DefaultNamespace").Value #><#= Path.GetDirectoryName(Host.TemplateFile).Remove(0, Path.GetDirectoryName(project.FileName).Length).Replace("\\", ".") #>
{
/// <summary>
/// <#= tableName #> auto generated enumeration by Karen Payne
/// </summary>
[GeneratedCode("TextTemplatingFileGenerator", "10")]
public enum <#= tableName #>
{
<#
SqlConnection conn = new SqlConnection(connectionString);
string command = string.Format("select {0}, {1}, {2} from {3} order by {0}", columnId, columnName, columnDescription, tableName);
SqlCommand comm = new SqlCommand(command, conn);
conn.Open();
SqlDataReader reader = comm.ExecuteReader();
bool loop = reader.Read();
while(loop)
{
#>
/// <summary>
/// <#= reader[columnName] #>
/// </summary>
<#= Pascalize(reader[columnName]) #> = <#= reader[columnId] #><# loop = reader.Read(); #><#= loop ? ",\r\n" : string.Empty #>
<#
}
#> }
}
<#+
private string Pascalize(object value)
{
Regex rx = new Regex(@"(?:[^a-zA-Z0-9]*)(?<first>[a-zA-Z0-9])(?<reminder>[a-zA-Z0-9]*)(?:[^a-zA-Z0-9]*)");
return rx.Replace(value.ToString(), m => m.Groups["first"].ToString().ToUpper() + m.Groups["reminder"].ToString().ToLower());
}
#>
图 2
[GeneratedCode("TextTemplatingFileGenerator", "10")]
public enum PersonTitle
{
/// <summary>
/// Mr
/// </summary>
Mr = 1,
/// <summary>
/// Miss
/// </summary>
Miss = 2,
/// <summary>
/// Mrs
/// </summary>
Mrs = 3,
/// <summary>
/// Dr
/// </summary>
Dr = 4
}
图 3
public enum PersonTitles : int
{
/// <summary>
/// Mr
/// </summary>
Mr = 1,
/// <summary>
/// Miss
/// </summary>
Miss = 2,
/// <summary>
/// Mrs
/// </summary>
Mrs = 3,
/// <summary>
/// Dr
/// </summary>
Dr = 4
}
推荐阅读
- python - 通过更新重复索引和外部连接其余部分来组合两个数据帧的最佳方法
- javascript - 动态创建的选项选择值
- php - TCPDF 和 base64 图像
- java - 当我尝试在 android studio 上运行构建时,我不断收到此错误
- mysql - 从两个级别查找儿童用户
- swift - 列表选择为 Set
- 如何使用? - python-3.x - 如何在熊猫中使用多个过滤器
- mysql - 如何通过在 mysql 中加载数据来解决此错误?
- javascript - 在焦点上添加柔和的光晕到输入
- firebase - 如何使用 Cloud Firestore 对聊天应用程序的聊天频道进行排序