将多个模型组合成 1 个 JSON WebAPI 响应
Combine multiple Models into 1 JSON WebAPI response
我在这里有点倒退,并尝试从提供的用于前端的 JSON 示例创建 Web api。这是 JSON 格式。
{"Sections": [{
"sectionID":"1",
"sectionOrder":1,
"sectionName":"Approach",
"sectionText": "",
"sectionContent": [{
"contentID": "1",
"contentTitle": "Definition",
"contentText": "Lorem Ipsum",
"contentImage": ""
},
{
"contentID": "2",
"contentTitle": "Vision",
"contentText": "Lorem Ipsum",
"contentImage": "image2.jpg"
}]
}]}
我创建了 2 tables(章节和章节内容由 SectionContentID 链接)并使用 entity framework 添加了 tables 作为模型。然后我为 return 部分 table 创建了一个控制器,但现在我陷入了如何将部分内容数据加入 1 JSON 响应的问题。
我的控制器看起来像这样:
public IQueryable<Sections> GetSections()
{
//how do I add db.SectionsContent to Sections linked by the sectionContentID field?
return db.Sections;
}
如果您正在使用 entity framework (EF) 并且您的 tables 关系类型是一对多,您可以在 lambda 表达式中使用 Include 来return 第一个 table 和第二个 table 的数据。
return context.Entity1st.Include(x => x.Entity2nd);
或者你也可以按照下面的方式做:
var entities = context.Entity1st;
foreach (var entity in entities)
{
entity.Entity2nd = context.Entity2nd.Where(x => x.Entity1stId == entity.Id);
}
return entities;
我会从定义 DTO object 开始,因为直接 returning 数据库 objects 不是最佳实践,您通常也不想修改所有字段它为您提供了更大的灵活性,可以在不破坏 API 合同的情况下更改数据库结构。此外,您还需要 collection 包含在 属性 部分中,因此您不能只是 return object 的列表。所以,你需要这样的结构:
public class SectionsResponse
{
public List<SectionDTO> Sections {get;set;}
}
public class SectionDTO
{
public string SectionID {get;set;}
.... add other properties
public List<ContentDTO> sectionContent {get;set;}
}
public class ContentDTO
{
... define your properties
}
下一步将实现数据库 object 和 DTO 之间的映射。您可以为此目的使用现有的库,例如AutoMapper
至于使用数据库,您可以从 Entity Framework 申请 eagerly loading。简而言之,它看起来像:
return db.Sections.Include(x => x.Content);
或使用 DTO 和 AutoMapper 包装:
return new SectionsResponse() { Sections = mapper.Map<List<Section>, List<SectionDTO>>(db.Sections.Include(x => x.Content)) };
我在这里有点倒退,并尝试从提供的用于前端的 JSON 示例创建 Web api。这是 JSON 格式。
{"Sections": [{
"sectionID":"1",
"sectionOrder":1,
"sectionName":"Approach",
"sectionText": "",
"sectionContent": [{
"contentID": "1",
"contentTitle": "Definition",
"contentText": "Lorem Ipsum",
"contentImage": ""
},
{
"contentID": "2",
"contentTitle": "Vision",
"contentText": "Lorem Ipsum",
"contentImage": "image2.jpg"
}]
}]}
我创建了 2 tables(章节和章节内容由 SectionContentID 链接)并使用 entity framework 添加了 tables 作为模型。然后我为 return 部分 table 创建了一个控制器,但现在我陷入了如何将部分内容数据加入 1 JSON 响应的问题。
我的控制器看起来像这样:
public IQueryable<Sections> GetSections()
{
//how do I add db.SectionsContent to Sections linked by the sectionContentID field?
return db.Sections;
}
如果您正在使用 entity framework (EF) 并且您的 tables 关系类型是一对多,您可以在 lambda 表达式中使用 Include 来return 第一个 table 和第二个 table 的数据。
return context.Entity1st.Include(x => x.Entity2nd);
或者你也可以按照下面的方式做:
var entities = context.Entity1st;
foreach (var entity in entities)
{
entity.Entity2nd = context.Entity2nd.Where(x => x.Entity1stId == entity.Id);
}
return entities;
我会从定义 DTO object 开始,因为直接 returning 数据库 objects 不是最佳实践,您通常也不想修改所有字段它为您提供了更大的灵活性,可以在不破坏 API 合同的情况下更改数据库结构。此外,您还需要 collection 包含在 属性 部分中,因此您不能只是 return object 的列表。所以,你需要这样的结构:
public class SectionsResponse
{
public List<SectionDTO> Sections {get;set;}
}
public class SectionDTO
{
public string SectionID {get;set;}
.... add other properties
public List<ContentDTO> sectionContent {get;set;}
}
public class ContentDTO
{
... define your properties
}
下一步将实现数据库 object 和 DTO 之间的映射。您可以为此目的使用现有的库,例如AutoMapper
至于使用数据库,您可以从 Entity Framework 申请 eagerly loading。简而言之,它看起来像:
return db.Sections.Include(x => x.Content);
或使用 DTO 和 AutoMapper 包装:
return new SectionsResponse() { Sections = mapper.Map<List<Section>, List<SectionDTO>>(db.Sections.Include(x => x.Content)) };