如何让EF Core数据库首次使用枚举?

时间:2017-05-30 12:28:18

标签: c# entity-framework-core

我正在使用EF Core和数据库优先方法,使用“Scaffold-DbContext”命令生成我的DbContext / Entities。

如何指示Scaffold-DbContext某个中的某个字段应该生成使用Enum而不仅仅是int的代码?

这是您在常规EF中执行此操作的方式: https://www.devu.com/cs-asp/lesson-69-mapping-enum-types-entity-properties-framework-designer/

实施例

此枚举已在代码中定义:

public enum StateEnum {
  Ok = 1,
  Fail = 2
}

这就是Scaffold-DbContext给我的

public partial class Foo
{
    public int Id { get; set; }
    public int State { get; set; }
}

这就是我想要创建的内容:

public partial class Foo
{
    public int Id { get; set; }
    public StateEnum State { get; set; }
}

9 个答案:

答案 0 :(得分:14)

EF Core 2.1中的值转换不是您现在需要的吗?

https://docs.microsoft.com/en-us/ef/core/modeling/value-conversions

快速示例:

  entity.Property(e => e.MyEnumField)
            .HasMaxLength(50)
            .HasConversion(
                v => v.ToString(),
                v => (MyEnum)Enum.Parse(typeof(MyEnum),v))
                .IsUnicode(false);

答案 1 :(得分:11)

我因为问题标题而来到这里。不确定这是否适用于" Scaffold-DbContext"但它在DbContext(Microsoft.EntityFrameworkCore 2.0.1.0)中通过显式设置枚举的基本类型来实现,即使枚举元素的默认基础类型是int。您也可以使用Fluent API为其设置默认值(尤其是枚举以1开头的情况)。

public enum StateEnum : int
{
    Ok = 1,
    Fail = 2
}
  

枚举的已批准类型是byte,sbyte,short,ushort,int,uint,long或ulong。

所以我认为这适用于任何这些。 enum (C# Reference)

public class MyDbContext : DbContext
{      
    protected override void OnModelCreating(ModelBuilder builder) 
    {
        builder.Entity<Foo>().Property(x => x.State).HasDefaultValue(StateEnum.Ok);
    }
}

答案 2 :(得分:8)

从Entity Framework Core 2.1 开始,EF支持Value Conversions来专门解决需要将属性映射到其他类型以进行存储的情况。

专门用于枚举,可以使用提供的EnumToStringConverterEnumToNumberConverter

答案 3 :(得分:3)

目前,EF core does not support enums。像这样的代码:

public class MyDbContext : DbContext
{      
    protected override void OnModelCreating(ModelBuilder builder) 
    {
        builder.Entity<StateEnum>(e => {...});
    }
}

不会使用以下消息进行编译:

  

CS0452 C#该类型必须是参考类型才能将其用作参数&#39; TEntity&#39;在通用类型或方法中

解决方案:您可以使用enumeration classes instead

答案 4 :(得分:3)

试试这个解决方案:

function update(id) {
    var quantity = $('#quantity' + id).html().trim();
    alert(quantity);
}

答案 5 :(得分:2)

这是回答的同一个问题: Does EF7 support enums?

答案 6 :(得分:1)

按照 link 中提供的 the accepted answer,我使用预定义的转换作​​为代码优先的方法,它使用 Entity Framework Core 5 工作:

modelBuilder.Entity<Model>(model => {
    model.Property(m => m.EnumType)
        .HasConversion<int>();
});

答案 7 :(得分:1)

接受的答案并不能解决问题。问题说明 “我如何指示 Scaffold-DbContext 某个表中的某个字段应该生成代码以使用 Enum 而不仅仅是一个 int?” 很多答案都表明,使用 Entity Framework Core 2.1,现在支持值转换。如果您使用代码优先,而不是数据库优先,这很有用。 Scaffold-DbContext 每次都会覆盖 DBContext。 就我个人而言,枚举是数据库中的整数没有问题。但我不想在代码中使用整数。

你可以

  1. 更改 DBContext 以使用 ValueConversion。每次搭建脚手架时,您都会丢失该代码。
  2. 将实体中的 Int 更改为特定的 Enum。它工作正常,但当你搭建脚手架时,你也会失去它。
  3. 创建一个分部类,您可以在其中创建一个名为 GetStateEnum() 和 SetStateEnum(StateEnum stateEnum) 等的方法。它非常冗长,但它会停留在脚手架之间。
  4. 有一种叫做 Source Generators 的东西也许可以在未来解决这个问题。我还没有找到一个简单的解决方案。

我选择了备选方案 2。这是我迄今为止发现的最简单的方案,而且使用 git-compare 恢复类非常容易。我可以在一分钟内更改我的所有枚举。

如果有人有更好的解决方案。请告诉我。

答案 8 :(得分:0)

您可以让您的枚举(U)和一个表示数据库中枚举值的实体(T)

public static T[] BuildEntityObjectsFromEnum<T, U>() where U: Enum where T : new()
    {
        var listObjectsToReturn = new List<T>();
        Dictionary<string, int> dictionary = Enum.GetValues(typeof(U)).Cast<U>().ToDictionary(t => t.ToString(), t =>  Convert.ToInt32(t));

        foreach (var item in dictionary)
        {
            var newObject = new T();
            Type classType = typeof(T);
            classType.GetProperties()[0].SetValue(newObject, item.Value); // Enum int id
            classType.GetProperties()[1].SetValue(newObject, item.Key); // Enum string value
            listObjectsToReturn.Add(newObject);
        }
        return listObjectsToReturn.ToArray();
    }

然后您可以从枚举中获取表的种子

modelBuilder.Entity<T>().HasData(BuildEntityObjectsFromEnum<T,U>());