有没有办法让我在实体框架中使用List<string>属性类?

问题描述 投票:0回答:4

这是班级:

namespace backend
{
    [Table("Products")]
    public class Product
    {
        public long Id { get; set; }
        [Required]
        public string? Name { get; set; }

        public string? Category { get; set; }

        public string? Short { get; set; }

        public string? Description { get; set; }
        [Required]
        public float Price { get; set; }

        public string? MainImage { get; set; }

        public float  Disccount { get; set; }
        
        public string[]? Images { get; set; } // List<string>

    }
}

我尝试运行 EF 迁移,但似乎不支持 [],如果我将其设为列表,它会要求提供此列表的键,但它只是一个字符串数组

我做错了什么?无法在 EF 中添加数组作为类属性吗?

c# .net entity-framework
4个回答
6
投票

这取决于用例。数据是否以关系子表方式(1:多)使用?或者它实际上只是一些在数据库中没有任何进一步关系的网址的列表?

第一种情况,请看Caius回答。第二种方法是编写类型转换器并将其注册到 EF 内核中。在这种情况下,数据库中的基础类型将是某种字符串(例如 nvarchar(max)),并且 EF core 在客户端进行转换

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder
        .Entity<Product>()
        .Property(e => e.Images)
        .HasConversion(
            v => JsonSerializer.Serialize(v),
            v => JsonSerializer.Deserialize<string[]>(v));
}

除了 JSON,您还可以使用其他方法,例如

string.Join()
string.Split()
,这取决于您。更多信息请参阅Microsoft 文档


3
投票

按照关系数据库的预期去做有什么问题:

namespace backend
{
    [Table("Products")]
    public class Product
    {
        public long Id { get; set; }
        [Required]
        public string? Name { get; set; }

        public string? Category { get; set; }

        public string? Short { get; set; }

        public string? Description { get; set; }
        [Required]
        public float Price { get; set; }

        public string? MainImage { get; set; }

        public float  Disccount { get; set; }
        
        public ICollection<ProductImage>? Images { get; set; } //make it a new hashset in the constructor, btw

    }

    [Table("ProductImages")]
    public class ProductImage
    {
        public long Id { get; set; }
        [Required]
        public string? Name { get; set; }

        public string? Url { get; set; }

        public long ProductId { get; set; }
        
        public Product? Product { get; set; }

}

通过这种方式,您可以向图像添加更多数据,例如“前视图”、“侧视图”、“版本 2”等,并且 EF 可以像它知道的那样映射它;作为 1:M 相关的单独表

无法在 EF 中添加数组作为类属性吗?

从技术上讲,

ICollection<ProductImage>
是一个“数组”属性..但开箱即用,不是基元数组,不


1
投票

string 是原始类型。您无法在实体框架中保存基本类型列表,而是可以将数据保存在一个属性(单个字符串)中,然后定义另一个属性来获取和设置主字符串属性。

 public class example {
    public string AttachmentsString { get ; set; }
    [NotMapped]
    public List<string> Attachments { 
        get => !string.IsNullOrEmpty(AttachmentsString) ? AttachmentsString.Split(",").ToList() : new List<string>(); 
        set => AttachmentsString = string.Join(",", value); 
    }
}

然后在您的控制器或服务中只需使用 Attachments 属性进行操作。


0
投票

现在 EF Core 8 原生支持此功能。您的 Images 属性将自动映射到数据库中同名的 JSON 列。

© www.soinside.com 2019 - 2024. All rights reserved.