【问题标题】:How to create a table corresponding to enum in EF Core Code First?如何在EF Core Code First中创建与枚举对应的表?
【发布时间】:2018-05-16 15:59:38
【问题描述】:

如何将 EF Core 数据库上下文中使用的枚举转换为查找表并添加相关的外键?


【问题讨论】:

标签: c# enums entity-framework-core


【解决方案1】:

您可以在代码中使用枚举,并通过结合使用这两个 EF Core 功能在数据库中创建查找表:


下面是一个数据模型示例:

public class Wine
{
    public int WineId { get; set; }
    public string Name { get; set; }

    public WineVariantId WineVariantId { get; set; }
    public WineVariant WineVariant { get; set; }
}

public enum WineVariantId : int
{
    Red = 0,
    White = 1,
    Rose = 2
}

public class WineVariant
{
    public WineVariantId WineVariantId { get; set; }
    public string Name { get; set; }

    public List<Wine> Wines { get; set; }
}

这里是DbContext,您可以在其中配置价值转换和数据播种:

public class WineContext : DbContext
{
    public DbSet<Wine> Wines { get; set; }
    public DbSet<WineVariant> WineVariants { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite("Data Source=wines.db");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder
            .Entity<Wine>()
            .Property(e => e.WineVariantId)
            .HasConversion<int>();

        modelBuilder
            .Entity<WineVariant>()
            .Property(e => e.WineVariantId)
            .HasConversion<int>();

        modelBuilder
            .Entity<WineVariant>().HasData(
                Enum.GetValues(typeof(WineVariantId))
                    .Cast<WineVariantId>()
                    .Select(e => new WineVariant()
                    {
                        WineVariantId = e,
                        Name = e.ToString()
                    })
            );
    }
}

然后您可以在代码中使用枚举值,如下所示:

db.Wines.Add(new Wine
{
    Name = "Gutturnio",
    WineVariantId = WineVariantId.Red,
});

db.Wines.Add(new Wine
{
    Name = "Ortrugo",
    WineVariantId = WineVariantId.White,
});

这是您的数据库将包含的内容:

我发布了完整的示例作为要点:https://gist.github.com/paolofulgoni/825bef5cd6cd92c4f9bbf33f603af4ff

【讨论】:

  • 您如何考虑未来迁移中 Enum 的变化?假设您要在枚举位置 3(当前为玫瑰)中插入一条记录,以便 wine.rose = 4 和 wine.blend = 3。创建的迁移更新了列,因此我所有的玫瑰酒现在都是混合的,玫瑰添加到结尾。 :(
  • @Itanex 如果您故意更改元素的 ID,我认为手动更改迁移是公平的。如果您想避免意外更改,那么在枚举中使用显式值可能会有所帮助,我将相应地更新示例
  • 感谢您的提示。我是这样倾斜的。只是希望有更好的方法。
  • @PaoloFulgoni,首先在数据库中,我们该怎么做?通过运行脚手架,dbContext 文件将被覆盖。
  • @MohammadTaherian 很抱歉,我对数据库优先方案一无所知
【解决方案2】:

这是另一个例子:

public class Weather {
        public int Id { get; init; }
        public WeatherType Type { get; init; }
    }

public enum WeatherType {
        Cloudy = 1,
        Sunny = 2,
        Rainy = 3,
    }

你可以像这样在一个单独的类中添加HasConversion

public class WeatherEntityTypeConfiguration : IEntityTypeConfiguration<Weather>
    {
        public void Configure(EntityTypeBuilder<Weather> builder)
        {
            builder.ToTable("Weather").HasKey(k => k.Id);

            builder.Property(p => p.Id).IsRequired();
            builder.Property(p => p.Type).HasConversion<int>().IsRequired(); 
            // builder.Property(p => p.Type).HasConversion<string>().IsRequired();
          
        }
    }

注意:如果您使用HasConversion&lt;int&gt;(),数据将作为integer存储在数据库中,但如果您使用HasConversion&lt;string&gt;(),数据将作为字符串存储(在此示例中:多云、晴天或下雨)

【讨论】:

    猜你喜欢
    • 2016-04-06
    • 1970-01-01
    • 1970-01-01
    • 2018-01-15
    • 1970-01-01
    • 1970-01-01
    • 2018-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多