我有一个List,其中包含以下内容:
{
Answer: "test answer",
FaqTopicName :"General",
Question: "test question",
SortOrder: 0
},
{
Answer: "...",
FaqTopicName :"General",
Question: "...",
SortOrder: 1
},
... (repeated)
我希望重新构建List,以便它现在包含在对象内部分组的每个列表项。结果对象将如下所示,并将包含属性名称“items”= []下具有相同FaqTopicName的所有项目。
我希望最终得到的数据格式:
{
topicName: "General",
items: {
Answer: "test answer",
Question: "test question",
SortOrder: 0
},
{
Answer: "...",
Question: "...",
SortOrder: 1
}
}
以下是我尝试过的内容,但它不正确,也不会通过JavaScriptSerializer()运行:
List<FaqQuestionAnswer> allFaqItemsInSelectedSytem = faqController.GetAllFaqItemsForSystem(out errors);
var groupedData = (from qaItem in allFaqItemsInSelectedSytem
group qaItem by qaItem.FaqTopicName
into questionsAnswersGroupedDataset
select questionsAnswersGroupedDataset).Distinct().ToDictionary(items => new { title = items.Key.ToString(), items = items.ToList() });
在调试器中产生这个:
[0] = {[{title = EBooks,items = System.Collections.Generic.List 1[JPay.Base.FaqQuestionAnswer] }, System.Linq.Lookup
2 + Grouping [System.String,JPay.Base.FaqQuestionAnswer]]}
但是当我通过JSON转换器运行它时会抛出类型错误:
输入'System.Collections.Generic.Dictionary 2[[<>f__AnonymousType0
2 [[System.String,mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = XXXXXXXXXXX],[System.Collections.Generic.List { {1}} 2 [[System.String,mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = XXXXXXXXXXXXX],[ttt.Base.FaqQuestionAnswer,tttBase,Version = 1.0.6180.30742,Culture = neutral,PublicKeyToken = null字典的序列化/反序列化不支持]],System.Core,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = XXXXXXXXXXXXXXXXX]]',键必须是字符串或对象。
感谢您的帮助。
答案 0 :(得分:0)
主要问题在于:
.ToDictionary(items => new { title = items.Key.ToString(), items = items.ToList() });
您可能认为自己正在使用Key = items.Key.ToString()
和Value = items.ToList()
定义字典,但实际上您使用的ToDictionary
overload具有以下签名:
public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector
)
因此,您将结果转换为一个奇怪的字典,其中匿名类型{ string title, IEnumerable<FaqQuestionAnswer> items }
作为键,IGrouping<string, IEnumerable<FaqQuestionAnswer>>
作为值。
如果你真的需要字典,那么你应该使用this overload代替:
public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
Func<TSource, TElement> elementSelector
)
像这样:
.ToDictionary(g => g.Key, g => g.ToList());
另请注意,Distict
之后的GroupBy
是多余的。
要获得您所描述的确切格式,您可以使用简单GroupBy
与自定义Select
:
var groupedData = allFaqItemsInSelectedSytem
.GroupBy(e => e.FaqTopicName)
.Select(g => new
{
topicName = g.Key,
items = g.Select(e => new { e.Answer, e.Question, e.SortOrder }).ToList()
}).ToList();
或者如果您更喜欢查询语法:
var groupedData =
(from e in allFaqItemsInSelectedSytem
group e by e.FaqTopicName into g
select new
{
topicName = g.Key,
items = (from e in g select new { e.Answer, e.Question, e.SortOrder }).ToList()
}).ToList();
答案 1 :(得分:0)
我最终得到了这个,这给了我需要的结果:
protected string GetJPayWebsiteFaqTopics()
{
// call the FAQ manager
var faqController = managers.GetFaqManager();
string errors = string.Empty;
string result = string.Empty;
// All items returned from faq manager, 2d collection not grouped into topic dictionaries
List<FaqQuestionAnswer> allFaqItemsInSelectedSystem = faqController.GetAllFaqItemsForSystem(out errors);
// Storage for main data, prior to serialization
List<Dictionary<string, object>> allFaqTopicsAndItems = new List<Dictionary<string, object>>();
// Group all item Lists together in alike topic related faq items
IEnumerable<IGrouping<string, FaqQuestionAnswer>> groupedData = from qaItem in allFaqItemsInSelectedSystem
group qaItem by qaItem.FaqTopicName;
// Allow the groupData to get iterated
IGrouping<string, FaqQuestionAnswer>[] enumerableGroups = groupedData as IGrouping<string, FaqQuestionAnswer>[] ?? groupedData.ToArray();
JavaScriptSerializer jsonConverter = new JavaScriptSerializer();
foreach (var instance in enumerableGroups)
{
// Each group of data should have a title for the group, a list of FAQ items
var items = instance.ToList();
// Temp storage for each topic and associated faq item data
Dictionary<string, object> group = new Dictionary<string, object>();
/**
* Temp storage for clean faq items stripped of topic level data which has now
* been added to the parent node so no longer needed at this level
*/
List<QuestionAnswerOrderOnly> cleanedItems = new List<QuestionAnswerOrderOnly>();
// Add the group title
group.Add("Title", instance.Key);
// Add the topics display order to the group data 1st item since it is on every item
group.Add("TopicOrder", items[0].TopicOrder);
/**
* Pull the values that are important for the item only, add it to the group
* Clean up item before recording it to the group it belongs to
*/
cleanedItems.AddRange(items.Select(item => new QuestionAnswerOrderOnly(item.Question, item.Answer, item.ItemOrder)));
// Add the clean faqitems collection
group.Add("Items", cleanedItems);
// Add this topic group to the result
allFaqTopicsAndItems.Add(group);
}
jsonConverter.MaxJsonLength = Int32.MaxValue;
try
{
result = jsonConverter.Serialize(allFaqTopicsAndItems);
}
catch (Exception error)
{
result = $"{errors} {error.Message}";
}
return result;
}
并输出以下内容:
{
topicName: "General",
items: {
Answer: "test answer",
Question: "test question",
SortOrder: 0
},
{
Answer: "...",
Question: "...",
SortOrder: 1
}
}
我希望这可以帮助处于类似情况的其他人。