更新:我找到了一种在 EntityFrameworkCore 5.0.8 中运行良好的更好方法
将 JsonConverter 属性添加到您的枚举中
[Newtonsoft.Json.JsonConverter(typeof(StringEnumConverter))]
public enum FacultyEnum
{
[EnumMember(Value = "English Professor")]
Eng,
[EnumMember(Value = "Math Professor")]
Math,
[EnumMember(Value = "Economics Professor")]
Eco
}
创建一个代表表格的类
public class Faculty
{
public int Id { get; set; }
public string Name { get; set; }
public FacultyEnum Description { get; set; }
}
在 DbContext 中的 OnModelCreating 中使用 Fluent API 以使用枚举字符串并设置检查约束
var enumToString = new EnumToStringConverter<FacultyEnum>();
modelBuilder.Entity<Faculty>(entity =>
{
entity.ToTable(nameof(FacultyMembers));
//convert enums to string
entity.Property(e => e.Description).HasConversion(enumToString);
//build check constraint from enum
var allowedEnumStrings = string.Join(',',
typeof(Faculty).GetMembers()
.Select(x => x.GetCustomAttribute(typeof(EnumMemberAttribute), false)).Where(x => x != null)
.Select(x => $"'{((EnumMemberAttribute)x).Value}'"));
entity.HasCheckConstraint($"CK_{nameof(FacultyMembers)}_{nameof(Faculty.Description)}", $"{nameof(Faculty.Description)} in ({allowedEnumStrings})");
});
老路
Alberto Monteiro 很好地回答了这个问题。我必须进行一些调整才能使其与 EF 核心一起使用。
重命名您的枚举并添加描述装饰器
public enum FacultyEnum
{
[Description("English Professor")]
Eng,
[Description("Math Professor")]
Math,
[Description("Economics Professor")]
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;
}
在 YourDbContext.cs 中添加种子
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Faculty>().HasData(FacultyEnum.Eng, FacultyEnum.Math, FacultyEnum.Eco);
}
在 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
var exampleFromDb = dbContext.Examples.Include(x => x.Faculty).SingleOrDefault(e => e.Id == 1);
if (example.Faculty == FacultyEnum.Math)
{
//code
}
如果 Faculty 属性是虚拟的,那么就使用它
var exampleFromDb = dbContext.Examples.Find(1);
if (example.Faculty == FacultyEnum.Math)
{
//code
}