我正在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":"[]"
。
我可以看到两种解决方案:
更容易的映射,无需第二个属性。
一种在调用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未映射。
答案 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的能力。在这种情况下将记录警告。正在考虑删除这些限制以用于将来的版本。