【问题标题】:Entity Framework 5 and Char Enums实体框架 5 和字符枚举
【发布时间】:2012-09-04 05:06:23
【问题描述】:

实体框架 5 可以处理字符枚举吗?我让它使用 int,但使用 char 我在数据库中的列是 char(1) 的地方得到错误。

The 'Gender' property on 'Division' could not be set to a 'String' value. You must set this property to a non-null value of type 'Gender'.

public enum Gender
{
    Male = 'M',
    Female = 'F'
}

【问题讨论】:

    标签: entity-framework enums char entity-framework-5


    【解决方案1】:

    您的枚举类型不是 char 类型,而是 int 类型。以下行将告诉您:

    Console.WriteLine(typeof(Gender).GetEnumUnderlyingType());
    
    System.Int32
    Press any key to continue . . .
    

    你的枚举成员的值实际上分别是 77 和 70:

    Console.WriteLine((int)Gender.Male);
    Console.WriteLine((int)Gender.Female);
    
    77
    70
    Press any key to continue . . .
    

    C#/VB.NET 中唯一有效的底层枚举类型是 byte、sbyte、short、ushort、int、uint、long 和 ulong。如果您尝试像这样放置不在此列表中的基础类型:

    public enum Gender : char
    { 
        Male = 'M', 
        Female = 'F' 
    }
    

    你会看到如下编译错误:

    error CS1008: Type byte, sbyte, short, ushort, int, uint, long, or ulong expected
    

    这是 C# 中枚举背后的理论。现在 EF 部分 - EF 目前仅支持以下枚举类型:Edm.Byte、Edm.SByte、Edm.Int16、Edm.Int32 和 Edm.Int64(Edm 类型系统没有无符号类型)。对于枚举属性,数据库中的相应列必须与属性的枚举类型的基础类型匹配(即,如果您的枚举属性的基础类型是 Edm.Int32,那么该列应该是 int 类型)。

    在您的情况下-如果您真的想使用枚举类型,则数据库中的列应该是 int 类型。添加实体时,您应该会在列中看到 70 和 77 的值。

    【讨论】:

    • SqlServer 似乎不支持 SByte,我不确定其他数据库是否支持。这确实意味着您在与 MSSQL 交互时不能使用 enum : sbyte 作为类型
    • 这个答案是 EF 特定的,而不是 Sql Server 特定的 - 从 EF 的角度来看,sbyte 是枚举类型的有效基础类型。对于 sbyte 类型不起作用的 Sql Server,您是正确的。
    【解决方案2】:

    这是我第一次使用 EF,我从 EF5 开始。所以当我试图解决这个问题时,我最终来到了这里。其他地方的答案非常令人困惑,但对我来说最明显的是下面的一个。

    我确实希望这是准确的,但对我来说似乎可以正常工作。

    我从 Postgres 导入了我的数据库

    在您的上下文中,您可以在其中定义列,在其中它们需要映射到与变量名称或类似名称不同的名称。

    您可以在此空间中进行转换。请参阅下面的博客以获得更好的解释。

    https://blog.bitscry.com/2019/07/29/converting-a-char-character-to-an-enum-in-entity-framework/

    我的比它需要的复杂一点。

    这是我的枚举表

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace DevDBStub.Models.DB
    {
        public class PreparationScreen
        {
            public enum CompleteMethods
            {
                Button = 'B',
                Timer  = 'T'
            }
    
            public int Id { get; set; }
            public string Descr { get; set; }
            public int NumberOfColumns { get; set; }
            public CompleteMethods CompleteMethod { get; set; }
            public int TimerSeconds { get; set; }
            public string DoneBy { get; set; }
            public DateTime TmStamp { get; set; }
        }
    }
    

    现在是我的上下文

    using System;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore.Metadata;
    
    #nullable disable
    
    namespace DevDBStub.Models.DB
    {
        public partial class ReactContext : DbContext
        {
            public ReactContext()
            {
            }
    
            public ReactContext(DbContextOptions<ReactContext> options)
                : base(options)
            {
            }
    
            public virtual DbSet<PreparationProfile> PreparationProfiles { get; set; }
    
            protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                modelBuilder.HasAnnotation("Relational:Collation", "en_ZA.UTF-8");
    
    
                modelBuilder.Entity<PreparationScreen>(entity =>
                {
                    entity.ToTable("preparationscreen");
    
                    entity.Property(e => e.Id).HasColumnName("id");
    
                    entity.Property(e => e.CompleteMethod)
                        .HasConversion<char>(p => (char)p, p => (PreparationScreen.CompleteMethods)p)
                        .HasColumnName("completemethod");
    
                    entity.Property(e => e.Descr)
                        .IsRequired()
                        .HasMaxLength(50)
                        .HasColumnName("descr");
    
                    entity.Property(e => e.DoneBy)
                        .IsRequired()
                        .HasMaxLength(16)
                        .HasColumnName("doneby");
    
                    entity.Property(e => e.NumberOfColumns).HasColumnName("numberofcolumns");
    
                    entity.Property(e => e.TimerSeconds).HasColumnName("timerseconds");
    
                    entity.Property(e => e.TmStamp).HasColumnName("tmstamp");
                });
            }
    
            partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
        }
    }
    

    【讨论】:

    • 什么是“HasColumnType”?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多