如何映射简单数据类型列表而不必对其进行字符串化?

时间:2019-05-24 17:06:12

标签: c# entity-framework-core

我正在C#.NET Core 2.2中创建API,并且试图弄清楚如何正确映射枚举和字符串列表。

现在我有以下解决方案:

        [NotMapped]
        public virtual IList<string> OtherNames { get; set; } = new List<string>();
        public string OtherName
        {
            get
            {
                return JsonConvert.SerializeObject(OtherNames);
            }
            set
            {
                OtherNames = JsonConvert.DeserializeObject<List<string>>(value);
            }
        }

,它可以像我想要的那样100%工作。但是,当我对具有OtherNames作为属性的对象执行HttpGet的API调用时,它将返回OtherNames和OtherName。这里是上下文的简化可视化: "otherNames":[],"otherName":"[]"

我可以看到两种解决方案:

  1. 更容易的映射,无需第二个属性。

  2. 一种在调用HttpGet时排除其中一个属性的方法。 ==>对于此解决方案,我将在此处添加HttpGet的负责代码:

这是所有返回的属性。

        public int Id { get; set; }
        public string Image { get; private set; }
        public string FirstName { get; private set; }
        public string LastName { get;  private set; }
        public Countries PlaceBorn { get; private set; }
        public DateTime WhenBorn { get; private set; }
        public DateTime? WhenDied { get; private set;}
        public string Description { get; set; }
        public Book Favorite { get; private set; }

        public IList<CelebrityRead> Read { get; set; } = new List<CelebrityRead>();
        public IList<Relationship> Relationships { get; set; } = new List<Relationship>();
        [NotMapped]
        public virtual IList<Countries> Nationalities { get; set; } = new List<Countries>();

        public string Nationality
        {
            get
            {
                return JsonConvert.SerializeObject(Nationalities);
            }
            set
            {
                Nationalities = JsonConvert.DeserializeObject<List<Countries>>(value);
            }
        }
        [NotMapped]
        public virtual IList<string> OtherNames { get; set; } = new List<string>();
        public string OtherName
        {
            get
            {
                return JsonConvert.SerializeObject(OtherNames);
            }
            set
            {
                OtherNames = JsonConvert.DeserializeObject<List<string>>(value);
            }
        }
        [NotMapped]
        public virtual IList<Jobs> Jobs { get; set; } = new List<Jobs>();
        public string Job
        {
            get
            {
                return JsonConvert.SerializeObject(Jobs);
            }
            set
            {
                Jobs = JsonConvert.DeserializeObject<List<Jobs>>(value);
            }
        }

控制器方法,调用存储库方法

        [HttpGet("{id}")]
        public ActionResult<Celebrity> GetCelebrity(int id)
        {
            var celeb = _celebrityRepository.GetBy(id);
            if (celeb == null) return NotFound();
            return celeb;
        }

存储库方法,由控制器方法调用

        public Celebrity GetBy(int id)
        {
            return _celebrities
              .Include(c => c.Favorite)
              .Include(c => c.Read)
              .Include(c => c.Relationships)
                .ThenInclude(r => r.With)
              .SingleOrDefault(c => c.Id == id);
        }

控制器返回

{"id":-1,"image":".png","firstName":"Louis","lastName":"Sachar","placeBorn":249,"whenBorn":"1954-03-20T00:00:00","whenDied":null,"description":"...","favorite":null,"read":[],"relationships":[],"nationalities":[],"nationality":"[]","otherNames":[],"otherName":"[]","jobs":[],"job":"[]"}

简单数据类型列表的当前映射由fluent API自动映射,因为它可以自动映射字符串属性OtherName。

OtherNames未映射。

1 个答案:

答案 0 :(得分:1)

选项1(“无需第二个属性的更轻松映射” )可以使用EF Core Value Conversions

  

值转换器允许在读取或写入数据库时​​转换属性值。此转换可以是从一个值到相同类型的另一个值(例如,加密字符串),也可以是从一种类型的值到另一种类型的值(例如,将枚举值与数据库中的字符串进行来回转换)。 / p>

基本上将其保留在实体类中

docker exec

并在模型配置中将值转换器与之关联:

public IList<string> OtherNames { get; set; } = new List<string>();

唯一的潜在问题可能是使用LINQ中的modelBuilder.Entity<Celebrity>() .Property(e => e.OtherNames) .HasConversion( value => JsonConvert.SerializeObject(value), dbValue => JsonConvert.DeserializeObject<List<string>>(dbValue)); 属性来进行实体查询(例如,执行过滤),如当前Value Conversion Limitations中所述:

  
      
  • 使用值转换可能会影响EF Core将表达式转换为SQL的能力。在这种情况下将记录警告。正在考虑删除这些限制以用于将来的版本。
  •