4

实体框架 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'
}
4

2 回答 2

8

您的枚举类型不是 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。

于 2012-09-11T18:10:09.720 回答
0

这是我第一次使用 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);
    }
}
于 2021-07-29T12:23:31.360 回答