首页 > 解决方案 > 如何在 Code First 中使用表值作为枚举?

问题描述

我有一张桌子,上面有先生、小姐、夫人、女士、博士等头衔

如果我使用 Code First 方法,如何将这些值用作枚举?特别是如果我想让它们在表格和 Code First 之间保持同步?

背景:我通过首先创建数据库然后使用 ADO .Net 实体数据模型来生成 Code First 模板进行反向工程,我可以将其用作指南,但不使用 Edmx 文件。

我看到一些带有 EDMX 文件的文章,但不是以这种方式?

标签: c#entity-frameworkentity-framework-6

解决方案


您可以创建一个 T4 模板(以下首先使用 Entity Framework 6 代码完成)。按照以下说明操作后,如果数据更改,则重新运行 T4。

以下GitHub 存储库中的完整源代码。

  • 添加一个名为 PersonTitle.ttinclude 的新文件。
  • 设置Custom toolTextTemplatingFileGenerator
  • 更改connectionString为您的数据库连接字符串
  • 在下面的示例中,我有三列,Id主键,Title用于先生,小姐,例如
  • columnDescription用于描述(这当然是可选的,但如果不存在,则将其从 select 语句中删除。

完成后,保存文件,您应该会收到一个提示,要求您继续,接受它。此时 Visual Studio 运行代码。如果有问题,它们将显示在“输出”窗口中。

如果没有问题,您将获得如下图 2 所示的输出。

新建一个文件,名称为PersonTitles.cs,复制图2中的代码,调整为图3。

作为演示,由于我没有准备好表/模型,以下摘自我的 Microsoft TechNet 文章Entity Framework database/Code First Enum supportCategoriesName是一个枚举。

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
}

在此处输入图像描述


推荐阅读