2016-02-11 11 views
7

Về cơ bản những gì tôi đang cố gắng làm là nhận được phụ huynh nhóm lại theo Parent.type nơi Child.type họ có tư cách 'y' lệnh của child.DateLINQ nhóm theo lệnh tài sản cha mẹ của đứa trẻ

Như một ví dụ i đã tạo các lớp này:

public class Collection 
{ 
    public IEnumerable<Parent> Parents { get; set; } 
    public int Id { get; set; } 
} 

public class Parent 
{ 
    public int Id { get; set; } 
    public Type type { get; set; }  
    public IEnumerable<Child> Children { get; set; } 
} 

public class Child 
{ 
    public int Id { get; set; } 
    public Status Status { get; set; } 
    public DateTime Date { get; set; } 
} 

public enum Type 
{ 
    a, 
    b 
} 

public enum Status 
{ 
    x, 
    y 
} 

Điều tôi muốn là danh sách Cha mẹ của từng loại mà Ngày của trẻ có giá trị cao nhất.

Để có được ví dụ này đi tôi đã thêm một số dữ liệu thử nghiệm:

Collection collection= new Collection 
     { 
      Id = 1, 
      Parents = new List<Parent> 
      { 
       new Parent 
       { 
        Id= 1, 
        type = Type.a, 
        Children = new List<Child> 
        { 
         new Child 
         { 
          Id = 1, 
          Status = Status.y, 
          Date = DateTime.Now.AddDays(-1) 
         }, 
         new Child 
         { 
          Id = 2, 
          Status = Status.x, 
          Date = DateTime.Now.AddDays(-1) 
         } 
        } 
       }, 
       new Parent 
       { 
        Id= 2, 
        type = Type.b, 
        Children = new List<Child> 
        { 
         new Child 
         { 
          Id = 3, 
          Status = Status.y, 
          Date = DateTime.Now.AddDays(-2) 
         }, 
         new Child 
         { 
          Id = 4, 
          Status = Status.x, 
          Date = DateTime.Now.AddDays(-2) 
         } 
        } 
       }, 
       new Parent 
       { 
        Id= 3, 
        type = Type.a, 
        Children = new List<Child> 
        { 
         new Child 
         { 
          Id = 5, 
          Status = Status.y, 
          Date = DateTime.Now.AddDays(-3) 
         } 
        } 
       }, 
       new Parent 
       { 
        Id= 4, 
        type = Type.b, 
        Children = new List<Child> 
        { 
         new Child 
         { 
          Id = 6, 
          Status = Status.y, 
          Date = DateTime.Now.AddDays(-3) 
         }, 
         new Child 
         { 
          Id = 7, 
          Status = Status.y, 
          Date = DateTime.Now.AddDays(-4) 
         }, 
         new Child 
         { 
          Id = 8, 
          Status = Status.x, 
          Date = DateTime.Now.AddDays(-4) 
         } 
        } 
       }, 
      } 
     }; 

Kết quả của chọn nên một danh sách chứa 2 phụ huynh. Một cho mỗi loại (a và b). Cả hai vẫn chứa tất cả các đối tượng con của chúng.

Có giải pháp đơn giản nào cho việc này không?

tôi đã cố gắng một cái gì đó như:

List<Parent> test = collection.Parents 
       .GroupBy(m => m.type) 
       .Select(
       m => m.OrderByDescending(
        mm => mm.Children.Select(
         r => r).OrderByDescending(
          r => r.Date)).FirstOrDefault()).ToList(); 

Nhưng điều đó không kết thúc tốt đẹp.

===== CẬP NHẬT =====

Nhờ ví dụ về vấn đề bí ẩn, vấn đề này được giải quyết. Tôi đã thực hiện một sửa đổi nhỏ đối với truy vấn LINQ vì nội dung gốc mà tôi đang sử dụng được cung cấp bởi Entity Framework (6). Điều này có nghĩa đối với tôi rằng đối tượng Parent đã chọn không chứa bất kỳ Children nào, vì vậy tôi phải chọn một kiểu đối tượng mới (Vì chúng ta không thể khởi tạo một đối tượng mới của kiểu được cung cấp bởi mô hình Entity Framework). Ngoài ra, cha mẹ của tôi đã ở một IEnumerable khác vì vậy tôi đã phải sử dụng một SelectMany trên Cha mẹ là tốt.

Điều này dẫn đến một cái gì đó như thế này: (Điều này sẽ không làm việc với các lớp học thử nghiệm mặc dù)

var result = 
    collection 
     .SelectMany(c => c.Parents) 
     .GroupBy(p => p.type) 
     .SelectMany(gps => 
      gps 
       .SelectMany(
        gp => gp.Children.Where(c => c.Status == Status.y), 
        (gp, c) => new { gp, c }) 
       .OrderByDescending(gpc => gpc.c.Date) 
       .Take(1) 
       .Select(gpc => new ParentData {Id = gpc.gp.Id, Children= gpc.gp.Children})) 
     .ToList(); 
+1

Well done để được như vậy mới đây và hỏi một câu hỏi chi tiết như vậy với mã biên dịch được. Hai bản sao chép nhanh và tôi đã có thể chạy mã của bạn. Tôi muốn thêm nhiều người dùng mới là tốt. – Enigmativity

Trả lời

1

Nếu tôi đã hiểu yêu cầu của bạn một cách chính xác bạn muốn nhóm tất cả các bậc phụ huynh theo loại và sau đó chọn chỉ có một mẹ từ mỗi nhóm dựa vào cha mẹ mà có một đứa trẻ có ngày cao nhất từ ​​tất cả trẻ em trong nhóm đó.

Đây là những gì tôi đã đưa ra:

var result = 
    collection 
     .Parents 
     .GroupBy(p => p.type) 
     .SelectMany(gps => 
      gps 
       .SelectMany(
        gp => gp.Children.Where(c => c.Status == Status.y), 
        (gp, c) => new { gp, c }) 
       .OrderByDescending(gpc => gpc.c.Date) 
       .Take(1) 
       .Select(gpc => gpc.gp)) 
     .ToList(); 

Đó mang lại cho tôi:

result

+0

"những gì tôi đang cố gắng làm là nhận được cha mẹ được nhóm theo Parent.type nơi Child.type của họ có trạng thái 'y' được đặt hàng bởi child.Date". Tôi không thấy điều đó trong kết quả của bạn – mariovalens

+0

@mariovalens - cố định. – Enigmativity

+0

vẫn sai. Ngài muốn tất cả những đứa trẻ có Tình trạng y. Bạn chỉ chọn các trẻ có Trạng thái y cho Phụ huynh đã chọn. Những gì anh ta thực sự muốn là những gì tôi đăng trong câu trả lời của tôi để thu gọn cha mẹ theo loại và tổng hợp tất cả các trẻ em cho rằng loại trạng thái y. – mariovalens

0

Trẻ em có thể không thực sự được lọc, sắp xếp, vv khi cha mẹ là những người mà các truy vấn/dự báo đang được áp dụng cho.

Bạn sẽ phải hoặc là:

  • Phá vỡ các mối quan hệ và dự án đến một cấu trúc dữ liệu khác nhau (như một cuốn từ điển hoặc IGrouping nơi phụ huynh là chìa khóa và các em được sắp xếp là giá trị)
  • phải nhất thiết Sort() hoặc phân công lại Children trong một vòng lặp mà không sử dụng LINQ
  • Viết lambdas nhiều dòng nơi dòng thứ hai là một tác dụng phụ như sắp xếp, chuyển nhượng quyền trẻ em (không khuyến khích)

Cá nhân tôi nghĩ sẽ dễ dàng hơn khi chỉ chiếu dữ liệu mà bạn cần đến một biểu diễn đơn giản hơn là cố gắng duy trì hệ thống phân cấp theo chiều hướng xuống.

0

Hiểu biết của tôi về câu hỏi là bạn cần phải tạo danh sách các phụ huynh được nhóm theo loại và tổng hợp tất cả các trẻ có trạng thái y cho từng loại cha mẹ. Đối với điều đó, xin lưu ý rằng bạn không thể thu gọn danh sách theo loại Cha mẹ và giữ cấu trúc gốc (có nghĩa là Id cũng bị thu gọn, tôi vừa lấy giá trị đầu tiên, tùy bạn chọn khác) .Nếu không điều này nên là giải pháp bạn đang tìm kiếm:

var result = collection.Parents.GroupBy(c => c.type) 
    .Select(g => new Parent 
       { 
        type = g.Key,  
        Id = g.Select(p => p.Id).FirstOrDefault(), 
        Children = g.SelectMany(p => p.Children 
           .Where(c => c.Status == Status.y) 
           .OrderByDescending(c => c.Date)).ToList()       
       }).ToList(); 
+0

Tôi có thể nhận được lý do tại sao câu trả lời đã được giảm giá? – mariovalens

+0

"Cả hai thứ này vẫn chứa tất cả các đối tượng con của chúng." - Mã của bạn tạo bố mẹ mới và điền chúng với con cái sai. – Enigmativity

+0

Sự kỳ thị, bạn đã thử chạy truy vấn để xem trẻ em có đúng không? Ông hy vọng tất cả các trẻ em có trạng thái 'Y', đó là ý nghĩa của tác giả bởi "tất cả các đối tượng con". Vâng, truy vấn tạo ra Phụ huynh mới và tôi đã giải thích lý do tại sao, và nó không nói rằng ông yêu cầu các đối tượng cha mẹ giống nhau. – mariovalens

Các vấn đề liên quan