创建DTO模型和LINQ

时间:2015-01-19 11:26:58

标签: c# linq asp.net-web-api2

我正在尝试在ASP Web API中创建以下输出:

User[] 
--> Category[]
     --> Transaction[]

所以我有很多用户有几个类别和很多与该类别相关的交易。 这似乎很容易但由于以下问题我无法使其工作: 我的数据库模型如下:

//Transaction
TransactionID
Quantity
CategoryID
UserID
//Category
ID
Name
//User
ID
Name

问题是返回json / xml响应,例如:

User1
--Cate1
----Tran1
----Tran2
--Cate2
----Tran3
User2
--Cate1
----Tran4

因为只有事务在User和Category之间没有单独的链接,我不知道如何使用LINQ查询或其他方法解决这个问题。

- 编辑 我的控制器代码:

        List<User> Users = new List<User> {
        new User {Id = 1, Name = "Matt" },
        new User {Id = 2, Name = "Bill" },
        new User {Id = 3, Name = "Peter" },
        new User {Id = 4, Name = "Bart" }
    };
    List<Category> Categories = new List<Category> {
        new Category {Id = 1, Name = "Sales" },
        new Category {Id = 2, Name = "After Sales" },
        new Category {Id = 3, Name = "Pre Sales" }
    };
    List<Transaction> Transactions = new List<Transaction> {
        new Transaction {Id = 1, Quantity = 200, CategoryId = 1 , UserId = 1},
        new Transaction {Id = 2, Quantity = 150, CategoryId = 2 , UserId = 1 },
        new Transaction {Id = 3, Quantity = 300, CategoryId = 2 , UserId = 1 },
        new Transaction {Id = 4, Quantity = 100, CategoryId = 1 , UserId = 2},
        new Transaction {Id = 5, Quantity = 150, CategoryId = 2 , UserId = 2 },
        new Transaction {Id = 6, Quantity = 250, CategoryId = 3 , UserId = 3 },
        new Transaction {Id = 7, Quantity = 200, CategoryId = 1 , UserId = 4},
        new Transaction {Id = 8, Quantity = 50, CategoryId = 2 , UserId = 4 },
        new Transaction {Id = 9, Quantity = 250, CategoryId = 3 , UserId = 4 }
    };
    //(new int[] { 2, 3, 5 });

    public List<UserDTO> Get()
    {
        var User = from d in Users
                   select new UserDTO
                   {
                       User = d,
                       /* Here I have the Problem
                        * I can't link the categories to the users without calling all transactions
                        * And then the result will for UserId = 1 will return 3 categories but 2 times After Sales and I want to return it onces
                       */
                       Categories = (from c in Transactions
                                     where c.UserId == d.Id
                                     select new CategoryDTO
                                     {
                                         Category = c.Category,
                                         Transactions = (from t in Transactions
                                                         where t.CategoryId == c.CategoryId && t.UserId == c.UserId
                                                         select new TransactionDTO
                                                         {
                                                             Id = t.Id,
                                                             Quantity = t.Quantity
                                                         }).ToList()
                                     }).ToList()

                   };
        return User.ToList();
    }

所有DTO课程:

    public class UserDTO
{
    public User User { get; set; }
    public List<CategoryDTO> Categories { get; set; }
}
public class CategoryDTO
{
    public Category Category { get; set; }
    public List<TransactionDTO> Transactions { get; set; }
}
public class TransactionDTO
{
    public int Id { get; set; }
    public int Quantity { get; set; }
}

由于

1 个答案:

答案 0 :(得分:1)

您需要按Category进行分组才能生成所需的输出:

var User = from d in Users
           select new UserDTO
           {
               User = d,
               Categories = (from t in Transactions
                             where t.UserId == d.Id
                             group t by t.Category into g   // <-- group by category
                             select new CategoryDTO
                             {
                                 Category = g.Key,
                                 Transactions = from ct in g
                                                 select new TransactionDTO
                                                 {
                                                     Id = ct.Id,
                                                     Quantity = ct.Quantity
                                                 }).ToList()
                             }).ToList()

           };
return User.ToList();

请注意,如果您的对象模型具有导航属性,那么 little 就更简单了:

var User = from d in Users
           select new UserDTO
           {
               User = d,
               Categories = (from t in d.Transactions
                             group t by t.Category into g   // <-- group by category
                             select new CategoryDTO
                             {
                                 Category = g.Key,
                                 Transactions = from ct in g
                                                 select new TransactionDTO
                                                 {
                                                     Id = ct.Id,
                                                     Quantity = ct.Quantity
                                                 }).ToList()
                             }).ToList()

           };
return User.ToList();

另一种选择是使用子模型将事务分组 - 这可能会减少让用户直接链接到类别(当他们真正属于事务时)的一些混淆。