2015-01-19 3 views
-3

Я пытаюсь создать следующий вывод в ASP веб API:Создание модели DTO и LINQ

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 

Поскольку между Пользователем и категорией нет отдельной связи только с транзакцией, и я не знаю, как я могу исправить это с помощью запросов LINQ или чего-то еще. Код

--edit My Controller:

 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; } 
} 

Благодаря

+0

Я смущен, вы говорите, что хотите вывести данные как «Пользователь -> Категория -> Транзакция», а затем пожаловаться, что это тип вывода, который вы получаете ... – James

+0

Нет примера в конце результат я хочу. Просто более подробно – Phoenix

+0

, но у вас уже есть отношения, покажите нам, что вы сейчас делаете, и почему оно не дает вам желаемого результата. – James

ответ

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(); 

Обратите внимание, что если ваш объект модель имела навигационные свойства, было бы немного проще:

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(); 

Другим вариантом было бы использовать суб-модели для групповых операций в категории - которые могли бы уменьшить некоторые из путаница того, что пользователи напрямую связаны с категориями (когда они действительно принадлежат транзакциям).

Смежные вопросы