将对象列表分组到json数组

时间:2015-05-19 18:05:48

标签: c# asp.net asp.net-mvc linq

我有一个像这样的对象列表:

CreateDate   Name     Unit
2015-01-01   Users     100
2015-01-01   Items      50
2015-01-02   Users     400
2015-01-02   Items     150

现在我想创建一个json数组,我在其中通过CreateDate对列表中的项进行分组并得到:

[
    {"CreateDate":"2015-01-01", "Users":100, "Items" : 50}, 
    {"CreateDate":"2015-01-02", "Users":400, "Items" : 150}
]

CreateDate和Name是数据库中的PK,包含更多类型的名称。

我有这个:

    public class Statistics
    {
        public DateTime CreateDate { get; set; }

        public int Unit { get; set; }

        public string Name { get; set; }
    }

    [HttpGet]
    public ActionResult Items(DateTime startDate, DateTime endDate)
    {
        try
        {
            List<Statistics> Coll = FROM DB

            var Data = Coll.GroupBy(p => p.CreateDate);

            return Json(Coll, JsonRequestBehavior.AllowGet);
        }
        catch (Exception Ex)
        {
            return ...
        }
    }

这样做的最佳方式是什么?

2 个答案:

答案 0 :(得分:1)

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication6
{

    public class Transactions
    {
        public string CreateDate { get; set; }
        public string Name { get; set; }
        public int Unit { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var transactionsList = new List<Transactions>();
            transactionsList.Add(new Transactions() { CreateDate = "2015-01-01", Name = "Users", Unit = 100 });
            transactionsList.Add(new Transactions() { CreateDate = "2015-01-01", Name = "Items", Unit = 50 });
            transactionsList.Add(new Transactions() { CreateDate = "2015-01-02", Name = "Users", Unit = 400 });
            transactionsList.Add(new Transactions() { CreateDate = "2015-01-02", Name = "Items", Unit = 150 });
            transactionsList.Add(new Transactions() { CreateDate = "2015-01-02", Name = "NewItems", Unit = 600 });

            var dictionaryList = new List<Dictionary<string, object>>();

            var transactionsQuery = (from t in transactionsList
                                     group t by new { t.CreateDate, t.Name }
                                         into grp
                                         select new
                                         {
                                             grp.Key.CreateDate,
                                             grp.Key.Name,
                                             Units = grp.Sum(t => t.Unit)
                                         }).ToList();

            var days = (from t in transactionsList
                        group t by new { t.CreateDate }
                            into grp
                            select grp.Key.CreateDate).ToList();


            foreach (string day in days)
            {
                var dataOfDay = new Dictionary<string, object>();
                dataOfDay.Add("CreateDate", day);
                foreach (var transaction in transactionsQuery.Where(x => x.CreateDate == day))
                {
                    dataOfDay.Add(transaction.Name, transaction.Units);
                }
                dictionaryList.Add(dataOfDay);
            }



            Console.WriteLine(JsonConvert.SerializeObject(dictionaryList));
            Console.ReadLine();

            // Output :
            // [{"CreateDate":"2015-01-01","Users":100,"Items":50},{"CreateDate":"2015-01-02","Users":400,"Items":150,"NewItems":600}]


        }
    }
}

答案 1 :(得分:0)

看起来你只需要使用LINQ重新整形数据。这将根据您提供的示例数据起作用:

var grouped = stats.GroupBy(x => x.CreateDate);

var data = grouped.Select(g => new { 
    CreateDate = g.Key, 
    // you might need to adjust the First() depending on whether you have nulls or multiples in your data
    Users = g.First(stat => stat.Name=="Users").Unit, 
    Items = g.First(stat => stat.Name=="Items").Unit 
});

修改

再考虑一下,如果你有一个日期的多个用户/项目,或者如果你有一个日期但没有项目行的用户行,这个LINQ语句可能会更安全:

var result = grouped.Select(g => new { 
    CreateDate = g.Key, 
    // you might need to adjust the First() depending on whether you have nulls or multiples
    Users = g.Where(stat => stat.Name=="Users").Sum(stat => stat.Unit), 
    Items = g.Where(stat => stat.Name=="Items").Sum(stat => stat.Unit) 
});

然后你应该把它吐到Json:

return Json(data, JsonRequestBehavior.AllowGet);