首页 > 解决方案 > 为什么实体框架在保存时将我的枚举重置为默认值

问题描述

我正在调试以下令人费解的行为。我有一个ExampleEntity包含[Required]枚举的实体,出于迁移原因,它具有默认值。插入新的ExampleEntity时,我指定了该字段应采用的值。在调试器中检查显示该值已在本地版本的DbSet. 但是,每当我调用SaveChanges()上下文时,枚举值都会重置为配置的默认值。

型号:

public enum ExampleEnum
{
    Mecury,
    Venus,
    Earth,
    Mars
}

internal class ExampleEntity
{
    public int id { get; set; }

    [Required]
    public ExampleEnum Val { get; set; }
}

internal class EFContext : DbContext
{
    public EFContext(DbContextOptions options) : base(options)
    {
    }

    public virtual DbSet<ExampleEntity> Ents { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
       modelBuilder.Entity<ExampleEntity>(entity =>
       {
            entity.Property(e => e.Val).HasDefaultValue(ExampleEnum.Earth);
       });
    }
}

测试代码:

class Program
{
    private static DbConnection CreateInMemoryDatabase()
    {
        var connection = new SqliteConnection("Filename=:memory:");
        connection.Open();
        return connection;
    }

    static void Main(string[] args)
    {
        var ContextOptions = new DbContextOptionsBuilder<EFContext>()
                .UseSqlite(CreateInMemoryDatabase())
                .Options;

        using (var context = new EFContext(ContextOptions))
        {
            context.Database.EnsureDeleted();
            context.Database.EnsureCreated();
        }

        using (var db = new EFContext(ContextOptions))
        {
            var newEntity = new ExampleEntity
            {
               Val = ExampleEnum.Mecury,
            };
            db.Ents.Add(newEntity);
            db.SaveChanges();
        }

        using (var db = new EFContext(ContextOptions))
        {
            var savedEnt = db.Ents.First();
            Console.WriteLine(savedEnt.Val.ToString());
        }
    }
}

我希望打印的值是,Mercury但它会打印出配置的 default Earth。我可以通过保存更改后解决此问题,将 设置Val为所需的值:

var newEntity = new ExampleEntity
{
   Val = ExampleEnum.Mecury,
};
db.Ents.Add(newEntity);
db.SaveChanges();
newEnttity.Val = ExampleEnum.Mecury;
db.SaveChanges()

标签: c#entity-frameworkentity-framework-core

解决方案


该问题是由使用默认值 Mecury (0) 引起的。实体框架可能无法区分未初始化的枚举和故意设置为 0 的枚举,因此它假定前者并设置默认值。

可能最简单的解决方法是使用零(第一个枚举值)作为默认值。在这种情况下,将枚举重新排序为:

Earth
Mecury
Venus
Mars

推荐阅读