我的结果集如下所示:
需要使用嵌套组格式化为hierarchal json:
[
{
areaName: "Latam",
subsidaries: [
{ areaName: "Ecuador", id: 1 },
{ areaName: "Peru", id: 3 },
{ areaName: "Jamaica", id: 4 },
{ areaName: "Venezuela", id: 5 },
{ areaName: "BCBB", id: 6 }
]
},
{
areaName: "APAC",
subsidaries: [
{ areaName: "Brunei", id: 1 },
{ areaName: "Sri Lanka", id: 31 },
{ areaName: "(APAC Sub Not Specified)", id: 1 },
{ areaName: "Korea", id: 231 },
{ areaName: "Malaysia", id: 61 },
{ areaName: "Indonesia", id: 61 },
{ areaName: "Philippines", id: 31 },
{ areaName: "Singapore", id: 3231 },
{ areaName: "Australia", id: 621 },
{ areaName: "New Zealand", id: 231 },
{ areaName: "Vietnam", id: 431 },
{ areaName: "Thailand", id: 99 }
]
}],
我最初的想法是使用linq查询对数据进行分组:
public ActionResult Index()
{
var model = Repository.GetGeoSubsidiaryHierarchy();
foreach (var line in GroupedItems(model)
.Select(group => new
{
AreaName = group.Key,
Count = group.Count()
}).OrderBy(x => x.AreaName))
{
Response.Write( String.Format( "{0} {1}", line.AreaName, line.Count) );
}
return View("Index", model);
}
private static IEnumerable<IGrouping<string, GeoSubsidiary>> GroupedItems(List<GeoSubsidiary> model)
{
var ret = model.ToList().GroupBy(area => area.AreaName);
return ret;
}
但我不清楚如何在分组后序列化此列表。此外,我对我的分组技能没有信心,因为我对子选择有点模糊,以便迭代每个分组的行(此代码:.Select(group =&gt; new)...)。
我考虑的其他选项是使用DataAnnotations / DataContracts和自定义注释类,利用Newtonsoft JSON.NET的一些高级功能,或使用字典并将其与分组行一起加载。
如果有人可以推荐处理分组数据和JSON的最佳实践并帮助我开始输出这个分组层次结构的代码(我手工构建的样本JSON数据,但确切需要),我将非常感激。输出)。
为了完整起见,我应该提一下,我的最终目标是成为一个很棒的剑道分层数据源javascript对象:http://docs.kendoui.com/api/framework/hierarchicaldatasource
答案 0 :(得分:1)
如果您只需要显示数据,您可以随时获取服务中的所有记录,并在javascript中进行分组,然后将分层数据源绑定到该数据。
示例http://jsbin.com/uQuLUwE/2/edit(我刚将其绑定到树视图以便于显示)
如果没有,您始终可以创建两个dataSource,一个用于根项目,另一个用于childItems。根项需要拉出不同的AreaNames,然后需要针对正确的AreaName过滤childItems数据源。
答案 1 :(得分:0)
感谢您的建议 - 我最终选择了一个可能过于复杂的c#方法
public class HierarchalDataController : BaseController
{
internal class ChildNode
{
public string areaName { get; set; }
public int id { get; set; }
}
internal class Area
{
public string areaName { get; set; }
public List<ChildNode> subsidaries { get; set; }
}
public ContentResult GetAreaContent()
{
var areas = Repository.GetGeoSubsidiaryHierarchy();
var groupedAreas = areas.GroupBy(area => area.AreaName);
var subareas = new List<Area>();
foreach (var parentArea in groupedAreas)
{
var subsidiaries = new List<ChildNode>();
var subs = areas.Where(x => x.AreaName == parentArea.Key).ToList();
subsidiaries.AddRange(subs.Select(sub => new ChildNode { id = sub.SubsidiaryId, areaName = sub.SubsidiaryName }));
var area = new Area { areaName = parentArea.Key, subsidaries = subsidiaries };
subareas.Add(area);
}
var retval = JsonConvert.SerializeObject(subareas, Formatting.Indented);
return Content(retval, "application/json");
}
public ContentResult GetScenarioContent()
{
var areas = Repository.GetScenarioHierarchy();
var groupedAreas = areas.GroupBy(area => area.FunctionalAreaID);
var subareas = new List<Area>();
foreach (IGrouping<int, Scenario> parentArea in groupedAreas)
{
var subsidiaries = new List<ChildNode>();
var subs = areas.Where(x => x.FunctionalAreaID== parentArea.Key).ToList();
subsidiaries.AddRange(subs.Select(sub => new ChildNode { id = sub.FunctionalAreaID, areaName = sub.ScenarioName}));
var scenario = parentArea.FirstOrDefault();
if (scenario != null)
{
var area = new Area { areaName = scenario.FunctionalAreaName, subsidaries = subsidiaries }; // hack
subareas.Add(area);
}
}
var retval = JsonConvert.SerializeObject(subareas, Formatting.Indented);
return Content(retval, "application/json");
}
/// <summary>
/// Simply a flat-list of products.
/// </summary>
/// <returns></returns>
public ContentResult GetProductContent()
{
var subareas = new List<Area>();
foreach (var product in Repository.GetProductList())
{
subareas.Add(new Area
{
areaName = product.ProductName,
subsidaries = new List<ChildNode>()
});
}
var retval = JsonConvert.SerializeObject(subareas, Formatting.Indented);
return Content(retval, "application/json");
}
}