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

查看:297
本文介绍了如何在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的例子中,不仅仅是获得了一个对应于部门的表格,而且我也想看到第二个表格,由 Faculty 中的项目填充。 p>

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; } 
}

重新启动问题,我偶然发现一个解决方案,其中建议为枚举创建一个表,并通过播种。

Resaerching 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.

我建议在您提供的文章中进行一些修改。 p>

重命名你的枚举



I suggest some modifications in article that you provided.

public enum FacultyEnum { Eng, Math, Eco }



创建一个代表表的类



Create a class that represent the table

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;
}



您的模型参考课程



Your model reference the class

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



创建扩展方法以从枚举和种子值获取描述



Create a extension method to get description from enum and seed values

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中添加种子



Add the seed in Configuration.cs

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



在您的DbContext


$中添加枚举表b $ b

Add the enum table in your DbContext

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



使用它



Use it

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

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



要记住



如果您不在Faculty属性中添加虚拟数据,则必须使用DbSet中的Include方法要加载

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
}

如果Faculty属性是虚拟的,那么只需使用它

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天全站免登陆