List EF Core中的枚举列表

List EF Core中的枚举列表,list,asp.net-core,enums,ef-core-3.1,List,Asp.net Core,Enums,Ef Core 3.1,是否可以在使用EF Core的项目中使用枚举列表来存储数据 我的枚举: public enum AudienceType { Child, Teen, [Display(Name ="Young Adult")] YoungAdult, Adult, Elderly } 使用枚举初始化: public class Restaurant { publi

是否可以在使用EF Core的项目中使用枚举列表来存储数据

我的枚举:

   public enum AudienceType
    {
        Child,
        Teen,
        [Display(Name ="Young Adult")]
        YoungAdult,
        Adult,
        Elderly
    }
使用枚举初始化:

public class Restaurant
{
    public int Id { get; set; }
    [Required, StringLength(80)]
    public string Name { get; set; }
    [Display(Name="Select the target audiences")]
    public List<AudienceType> AudienceTypes { get; set; }
}
更新:
我了解了如何使用值转换来处理枚举,如下所示:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    var converter = new EnumToStringConverter<AudienceType>();

    modelBuilder
        .Entity<Restaurant>()
        .Property(e => e.AudienceTypes)
        .HasConversion(converter);
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
基于模型创建(modelBuilder);
var converter=新的EnumToStringConverter();
建模者
.实体()
.Property(e=>e.AudienceType)
.转换(转换器);
}

但是如何处理枚举列表呢?

要将枚举值列表表示为逗号分隔的字符串,可以使用值转换

最简单的“内联”选项:

//在DbContext类中
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
建模者
.实体()
.Property(e=>e.AudienceType)
.哈斯转换(
v=>string.Join(v.Select(e=>e.ToString(“D”)).ToArray(),
v=>v.Split(新[]{',})
.Select(e=>Enum.Parse(typeof(audenceType),e))
.Cast()
托利斯先生()
);
}

因为enum不是一个类,所以需要编写一个新类来封装它

您可以创建一个新类:

public class Audience
{
    public int Id { get; set; }
    public AudienceType AudienceType { get; set; }
}
然后在您的
餐厅

    public class Restaurant
{
    public int Id { get; set; }
    [Required, StringLength(80)]
    public string Name { get; set; }
    [Display(Name="Select the target audiences")]
    public List<Audience> Audiences{ get; set; }
}
公共级餐厅
{
公共int Id{get;set;}
[所需长度(80)]
公共字符串名称{get;set;}
[显示(Name=“选择目标受众”)]
公共列表访问群体{get;set;}
}
如果需要转换,可以在dbcontext中进行转换

   modelBuilder.Entity<Audience>().Property(b => b.AudienceType).HasConversion(
            v => v.ToString(), v => (AudienceType)Enum.Parse(typeof(AudienceType), v));
modelBuilder.Entity().Property(b=>b.AudienceType).HasConversion(
v=>v.ToString(),v=>(AudienceType)Enum.Parse(typeof(AudienceType),v));
然后迁移和更新数据库。您将获得它们之间的一对多关系。

我发现这很有用,这导致了以下解决方案:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        var converter = new EnumCollectionJsonValueConverter<AudienceType>();
        var comparer = new CollectionValueComparer<AudienceType>();

        modelBuilder.Entity<Restaurant>()
          .Property(e => e.AudienceTypes)
          .HasConversion(converter)
          .Metadata.SetValueComparer(comparer);
   }
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
基于模型创建(modelBuilder);
var converter=new EnumCollectionJsonValueConverter();
var comparer=新的CollectionValueComparer();
modelBuilder.Entity()
.Property(e=>e.AudienceType)
.HasConversion(转换器)
.Metadata.SetValueComparer(比较器);
}
它使用以下两个类:

public class EnumCollectionJsonValueConverter<T> : ValueConverter<ICollection<T>, string> where T : Enum
{
    public EnumCollectionJsonValueConverter() : base(
      v => JsonConvert
        .SerializeObject(v.Select(e => e.ToString()).ToList()),
      v => JsonConvert
        .DeserializeObject<ICollection<string>>(v)
        .Select(e => (T)Enum.Parse(typeof(T), e)).ToList())
    {
    }
   }

public class CollectionValueComparer<T> : ValueComparer<ICollection<T>>
{
    public CollectionValueComparer() : base((c1, c2) => c1.SequenceEqual(c2),
      c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())), c => (ICollection<T>)c.ToHashSet())
    {
    }
}
公共类EnumCollectionJsonValueConverter:ValueConverter其中T:Enum
{
public EnumCollectionJsonValueConverter():base(
v=>JsonConvert
.SerializeObject(v.Select(e=>e.ToString()).ToList()),
v=>JsonConvert
.反序列化对象(v)
.Select(e=>(T)Enum.Parse(typeof(T),e)).ToList()
{
}
}
公共类集合ValueComparer:ValueComparer
{
public CollectionValueComparer():基((c1,c2)=>c1.SequenceEqual(c2),
c=>c.Aggregate(0,(a,v)=>HashCode.Combine(a,v.GetHashCode()),c=>(ICollection)c.ToHashSet())
{
}
}

您希望如何在数据库中“表示”枚举列表?逗号分隔的字符串或例如每个枚举值都有一个单独的表是一条记录。我对逗号分隔的字符串没意见。然后看看我知道如何使用值转换来处理枚举,但是如何处理枚举列表?当我尝试此操作时,HasVersion的第一个参数出现错误:
无法从'System.Collections.Generic.IEnumerable'转换为'char'
使用char数组替换
Split
方法的参数。如果我将HasConversion的第一个参数替换为'v=>string.Join(,“,”,v.选择(s=>s.ToString()).ToArray()`然后
v.Split(“,”)
在第二个参数中生成以下错误:
表达式树可能不包含使用可选参数的调用或调用
我喜欢枚举的便利性,我可以直接在razor页面中使用它:
有没有一种简单的方法可以对类执行此操作?(可能我缺少它)
courine
是您的枚举吗?很抱歉,复制了错误的代码行,已将其修复。这没关系,但绑定模型时会出现问题,这会使问题变得复杂。因此,如果您想要进行模型绑定,您的方法确实更简单。
public class EnumCollectionJsonValueConverter<T> : ValueConverter<ICollection<T>, string> where T : Enum
{
    public EnumCollectionJsonValueConverter() : base(
      v => JsonConvert
        .SerializeObject(v.Select(e => e.ToString()).ToList()),
      v => JsonConvert
        .DeserializeObject<ICollection<string>>(v)
        .Select(e => (T)Enum.Parse(typeof(T), e)).ToList())
    {
    }
   }

public class CollectionValueComparer<T> : ValueComparer<ICollection<T>>
{
    public CollectionValueComparer() : base((c1, c2) => c1.SequenceEqual(c2),
      c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())), c => (ICollection<T>)c.ToHashSet())
    {
    }
}