【问题标题】:Entity Framework Core 3.1 Enum Conversion failed when converting the nvarchar value 'EnumValue' to data type int将 nvarchar 值“EnumValue”转换为数据类型 int 时,Entity Framework Core 3.1 枚举转换失败
【发布时间】:2020-04-05 15:56:10
【问题描述】:

我正在使用 Entity Framework Core 3.1 并尝试对我的 localdb 中的实体中的枚举属性进行简单查询,但我不断收到此错误:

将 nvarchar 值 'Accountant' 转换为数据类型 int 时枚举转换失败

实体:

public class DemoEntity
{
    [Key]
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Position Position { get; set; }
}

枚举 - 位置:

public enum Position
{
    [Display(Name = "Accountant")]
    Accountant,
    [Display(Name = "Chief Executive Officer (CEO)")]
    ChiefExecutiveOfficer,
    [Display(Name = "Integration Specialist")]
    IntegrationSpecialist,
    [Display(Name = "Junior Technical Author")]
    JuniorTechnicalAuthor,
    [Display(Name = "Pre Sales Support")]
    PreSalesSupport,
    [Display(Name = "Sales Assistant")]
    SalesAssistant,
    [Display(Name = "Senior Javascript Developer")]
    SeniorJavascriptDeveloper,
    [Display(Name = "Software Engineer")]
    SoftwareEngineer
}

数据库上下文:

public class DemoDbContext : DbContext
{
    public DemoDbContext(DbContextOptions options)
        : base(options) { }

    public DbSet<DemoEntity> Demos { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        //var converter = new ValueConverter<Position, string>(
        //                    v => v.ToString(),
        //                    v => (Position)Enum.Parse(typeof(Position), v));

        //var converter = new EnumToStringConverter<Position>();

        modelBuilder
            .Entity<DemoEntity>()
            .Property(e => e.Position);
            //.HasColumnType("nvarchar(max)")
            //.HasConversion<string>();
            //.HasConversion(converter);
    }
}

我尝试增加价值转换:

  1. .HasConversion&lt;string&gt;() - 没用
  2. .HasConversion(converter) - 没用

当我按如下方式查询表时,出现转换错误

try
{
    var test = await query.Where(x => x.Position.Equals(Position.Accountant)).ToListAsync();
}
catch (System.Exception e)
{
    //throw;
}

Position 在我的数据库中属于NVARCHAR(MAX) 类型。

我错过了什么简单的东西吗?无法弄清楚我要去哪里错了。请协助。

【问题讨论】:

  • .HasConversion&lt;string&gt;() 是正确的映射。什么“没用”?
  • 我尝试添加.HasConversion&lt;string&gt;()。当查询被执行时,我得到了同样的错误。
  • 我将查询修改为query.Where(x =&gt; x.Position.Equals(Position.Accountant.ToString())).ToListAsync()。现在查询执行但我得到零结果。有什么想法吗?
  • 谢谢,我能够重现它。又一个 EFC 错误。

标签: c# enums entity-framework-core entity-framework-core-3.1


【解决方案1】:

由于底层数据库列类型是字符串,因此关联值转换器是正确的映射(默认情况下,EF Core 将enums 映射到int)。

所以这样的事情是必须的

modelBuilder.Entity<DemoEntity>()
    .Property(e => e.Position)
    .HasConversion<string>();

这导致了最初的问题。看起来您遇到了 EF Core 查询翻译错误 - 表达式

x.Position.Equals(Position.Accountant)

被错误地翻译成类似

WHERE [d].[Position] = 0

而不是预期

WHERE [d].[Position] = N'Accountant'

解决方案是使用比较运算符(==!=)而不是Equals

x.Position == Position.Accountant

翻译正确。

当有相应的 C# 运算符时,通常避免使用 Equals(和 CompareCompareTo 等)方法。

【讨论】:

    猜你喜欢
    • 2020-04-17
    • 2011-08-29
    • 2015-06-20
    • 2016-02-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多