如何在EF6 Code First中创建对应于枚举的表? [英] How to create a table corresponding to enum in EF6 Code First?

查看:20
本文介绍了如何在EF6 Code First中创建对应于枚举的表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已关注 MSDN 关于如何处理代码中的枚举首先是 EF6.它可以正常工作,但是创建的表中引用枚举器的字段是一个简单的int.

I've followed MSDN on how to handle enumerations in Code First for EF6. It worked, as supposed to but the field in the created table that refers to the enumerator is a simple int.

我更喜欢生成第二个表,其值将遵循 C# 代码中枚举器的定义.因此,在 MSDN 上的示例中,我不仅希望获得与 Department 相对应的表格,还希望看到第二个表格,其中包含来自 Faculty 的项目.>

I'd prefer a second table to be produced, the values of which would follow the definition of the enumerator in C# code. So, instead of only getting a table corresponding to Department in the example on MSDN, I'd also like to see a second table populated by the items from Faculty.

public enum Faculty { Eng, Math, Eco }     

public partial class Department 
{ 
  [Key] public Guid ID { get; set; } 
  [Required] public Faculty Name { get; set; } 
}

在研究这个问题时,我偶然发现了一个 解决方案,它建议为枚举创建一个表并通过播种明确填充它.

Researching the issue, I stumbled upon a solution, which suggests creating a table for the enumeration and populating it explicitly by seeding.

在我看来,这是一种繁琐的方法,需要自动处理大量工作.毕竟,系统知道构成枚举的实际值.从 DB 的角度来看,它仍然是数据行,就像我创建的实体一样,但从 OO 方面来看,它并不是真正的数据 - 而是一种类型(松散表达),可以假设有限且事先已知的状态数.

It appear to me as a cumbersome approach and a lot of work that should be handled automagically. After all, the system knows what actual values that constitute the enumeration. From DB point of view it's still data rows, just as the entities that I create but from OO aspect, it's not really a data - rather a type (loosely expressed) that can assume a finite and onbeforehand known number of states.

是否推荐手动"填充表格的方法?

Is the approach of populating the table "manually" recommended?

推荐答案

由于 EF 不会自动处理,是的,这是推荐的方式.

Since EF doesn't handle it automatically, yes, this is the recommend way.

我建议对您提供的文章进行一些修改.

I suggest some modifications in article that you provided.

public enum FacultyEnum { Eng, Math, Eco }

创建一个表示表的类

public class Faculty
{
    private Faculty(FacultyEnum @enum)
    {
        Id = (int)@enum;
        Name = @enum.ToString();
        Description = @enum.GetEnumDescription();
    }

    protected Faculty() { } //For EF

    [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }

    [Required, MaxLength(100)]
    public string Name { get; set; }

    [MaxLength(100)]
    public string Description { get; set; }

    public static implicit operator Faculty(FacultyEnum @enum) => new Faculty(@enum);

    public static implicit operator FacultyEnum(Faculty faculty) => (FacultyEnum)faculty.Id;
}

您的模型引用了类

public class ExampleClass
{
    public virtual Faculty Faculty { get; set; }
}

创建一个扩展方法来从枚举和种子值中获取描述

using System;
using System.ComponentModel;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;

public static class Extensions
{
    public static string GetEnumDescription<TEnum>(this TEnum item)
        => item.GetType()
               .GetField(item.ToString())
               .GetCustomAttributes(typeof(DescriptionAttribute), false)
               .Cast<DescriptionAttribute>()
               .FirstOrDefault()?.Description ?? string.Empty;

    public static void SeedEnumValues<T, TEnum>(this IDbSet<T> dbSet, Func<TEnum, T> converter)
        where T : class => Enum.GetValues(typeof(TEnum))
                               .Cast<object>()
                               .Select(value => converter((TEnum)value))
                               .ToList()
                               .ForEach(instance => dbSet.AddOrUpdate(instance));
}

在 Configuration.cs 中添加种子

protected override void Seed(Temp.MyClass context)
{
    context.Facultys.SeedEnumValues<Faculty, FacultyEnum>(@enum => @enum);
    context.SaveChanges();
}

在您的 DbContext 中添加枚举表

public class MyClass : DbContext
{
    public DbSet<ExampleClass> Examples { get; set; }
    public DbSet<Faculty> Facultys { get; set; }
}

使用它

var example = new ExampleClass();
example.Faculty = FacultyEnum.Eng;

if (example.Faculty == FacultyEnum.Math)
{
    //code
}

记住

如果你没有在 Faculty 属性中添加 virtual,你必须使用 DbSet 中的 Include 方法来做 Eager Load

To remember

If you don't add virtual in Faculty property, you must use Include method from DbSet to do Eager Load

var exampleFromDb = dbContext.Examples.Include(x => x.Faculty).SingleOrDefault(e => e.Id == 1);
if (example.Faculty == FacultyEnum.Math)
{
    //code
}

如果教师财产是虚拟的,那么就使用它

If Faculty property is virtual, then just use it

var exampleFromDb = dbContext.Examples.Find(1);
if (example.Faculty == FacultyEnum.Math)
{
    //code
}

这篇关于如何在EF6 Code First中创建对应于枚举的表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆