Могу ли я получить JavaScriptSerializer для иерархической сериализации результата LINQ?

#.net #linq #json #javascriptserializer

#.net #linq #json #javascriptserializer

Вопрос:

Я делаю это:

 var data = from a in attributes
           from i in attributeItems.Where(x=>x.DocClassAttributeFieldId == a.Id )
           .DefaultIfEmpty(new DocClassAttributeFieldItem())
                select new
                {
                    Id = a.Id,
                    LabelText = a.LabelText,
                    Items = i
                };

JavaScriptSerializer serializer = new JavaScriptSerializer();
TextBox1.Text = serializer.Serialize(data);
  

Результат таков:

 [{
    "Id": 1,
    "LabelText": "Unit On-Line Status:",
    "Items": {
        "Id": 1,
        "DocClassAttributeFieldId": 1,
        "LabelText": "Online",
        "ValueText": "Online",
        "Ordering": 1
    }
},
{
    "Id": 1,
    "LabelText": "Unit On-Line Status:",
    "Items": {
        "Id": 2,
        "DocClassAttributeFieldId": 1,
        "LabelText": "Offline",
        "ValueText": "Offline",
        "Ordering": 2
    },
}]
  

Я хотел бы получить результат, подобный этому:

 [{    
    "Id": 1,    
    "LabelText": "Unit On-Line Status:",    
    "Items": [{    
        "Id": 1,    
        "DocClassAttributeFieldId": 1,    
        "LabelText": "Online",    
        "ValueText": "Online",    
        "Ordering": 1    
    },{    
        "Id": 2,    
        "DocClassAttributeFieldId": 1,    
        "LabelText": "Offline",    
        "ValueText": "Offline",    
        "Ordering": 2    
    }]    
}]
  

Можно ли это легко сделать с помощью JavaScriptSerializer или для этого можно переработать инструкцию LINQ?

Обновление: Благодаря некоторым сообщениям, подобным этим…

http://encosia.com/asp-net-web-services-mistake-manual-json-serialization/

http://encosia.com/using-complex-types-to-make-calling-services-less-complex/

Я не собираюсь использовать JavaScriptSerializer, ASP.Net делает все это за меня:

 [WebMethod]
public static object GetDocClass(int docClassId)
{
    var data = from a in attributes                       
        select new
        {
            Id = a.Id,
            LabelText = a.LabelText,
            Items = attributeItems.Where(x=>x.DocClassAttributeFieldId == a.Id)                    
        };          
    return data;
}
  

Ответ №1:

Вы можете это сделать, но вам нужно использовать group into для заполнения элементов.

 var data = 
       from a in attributes
       from i in attributeItems.Where(x=>x.DocClassAttributeFieldId == a.Id )
       group a by a.Id, a.LabelText into myGroup
       .DefaultIfEmpty(new DocClassAttributeFieldItem())
            select new
            {
                Id = a.Id,
                LabelText = a.LabelText,
                Items = myGroup.ToList()
            };

JavaScriptSerializer serializer = new JavaScriptSerializer();
TextBox1.Text = serializer.Serialize(data);
  

Это был неожиданный шаг, поэтому дайте мне знать, если у вас это не сработает.

Ответ №2:

Вероятно, есть способ получше, но ответ Nix помог мне придумать это:

 var data = from a in attributes                       
            select new
            {
                Id = a.Id,
                LabelText = a.LabelText,
                Items = attributeItems.Where(x=>x.DocClassAttributeFieldId == a.Id)                    
            };

JavaScriptSerializer serializer = new JavaScriptSerializer();
TextBox1.Text = serializer.Serialize(data);