使用LinQ

时间:2016-11-16 05:43:51

标签: c# linq

我的示例包含2个表BookComment

Book

Id           Name           UserId           DateTime

B1           Book1          User1            16/11/2016 11:15:00
B2           Book2          User1            16/11/2016 12:15:00
B3           Book3          User2            16/11/2016 10:15:00

Comment

Id           BookId        UserId            DateTime

C1           B3            User1             16/11/2016 11:17:00
C2           B1            User1             16/11/2016 11:16:00

通过特定用户ID的Book列表:

string userid = "User1";

IEnumerable<Book> books = _context.Books.Where(x => x.UserId == userid);

Comment的列表:

IEnumerable<Book> comments = _context.Comments.Where(x => x.UserId == userid);

在活动历史记录(网页)中,我想逐一显示我通过books收集的所有commentsuserid。但是,如何通过.OrderByDescending(x => x.DateTime)再次对2个对象进行排序?

我的目标:

User1刚给商店出了一本新书:

B2           Book2          User1            16/11/2016 12:15:00

在此之前,他在自己的帖子中发表评论:

C1           B1            User1             16/11/2016 11:17:00

之前,他在另一个帖子(UserId == "User2")中发表了评论:

C2           B3            User1             16/11/2016 11:16:00

年纪较大,他向商店贴了一本新书:

B1           Book1          User1            16/11/2016 11:15:00

我可以通过DateTime栏(纸上)对其进行分类:

16/11/2016 12:15:00
16/11/2016 11:17:00
16/11/2016 11:16:00
16/11/2016 11:15:00

我该如何排序?

更新

我刚刚找到了一个解决方案,但LinQ。我想要一个使用LinQ的解决方案,结果相同(更短):

namespace MP
{
    public class Book
    {
        public string Id { get; set; }

        public string Name { get; set; }

        public string UserId { get; set; }

        public DateTime DateTime { get; set; }
    }

    public class Comment
    {
        public string Id { get; set; }

        public string BookId { get; set; }

        public string UserId { get; set; }

        public string Content { get; set; }

        public DateTime DateTime { get; set; }
    }

    public class Result
    {
        public object Object { get; set; }

        public DateTime DateTime { get; set; }
    }

    class Program
    {
        static void Main()
        {
            try
            {
                string userid = "User1";

                var books = new List<Book>();
                books.Add(new Book { Id = "B1", Name = "Book1", UserId = "User1", DateTime = new DateTime(2016, 11, 16, 11, 15, 00) });
                books.Add(new Book { Id = "B2", Name = "Book2", UserId = "User1", DateTime = new DateTime(2016, 11, 16, 12, 15, 00) });
                books.Add(new Book { Id = "B3", Name = "Book3", UserId = "User2", DateTime = new DateTime(2016, 11, 16, 10, 15, 00) });

                var comments = new List<Comment>();
                comments.Add(new Comment { Id = "c1", BookId = "B3", UserId = "User1", Content = "cmt1", DateTime = new DateTime(2016, 11, 16, 11, 17, 00) });
                comments.Add(new Comment { Id = "c2", BookId = "B1", UserId = "User1", Content = "cmt2", DateTime = new DateTime(2016, 11, 16, 11, 16, 00) });

                var result = new List<Result>();
                books.ForEach(x => 
                {
                    if (x.UserId == userid)
                    {
                        result.Add(new Result { Object = x, DateTime = x.DateTime });
                    }                    
                });

                comments.ForEach(x =>
                {
                    if (x.UserId == userid)
                    {
                        result.Add(new Result { Object = x, DateTime = x.DateTime });
                    }
                });

                result = result.OrderByDescending(x => x.DateTime).ToList();

                foreach (var item in result)
                {
                    Type type = item.Object.GetType();

                    if (type == typeof(MP.Book))
                    {
                        var book = (Book)item.Object;

                        Console.WriteLine($"Book: Id: {book.Id} - Name: {book.Name} - DateTime: {book.DateTime}");
                    }

                    if (type == typeof(MP.Comment))
                    {
                        var cmt = (Comment)item.Object;

                        Console.WriteLine($"Comment: Id: {cmt.Id} - Content: {cmt.Content} - DateTime: {cmt.DateTime}");
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }
}

结果:

1

4 个答案:

答案 0 :(得分:1)

请尝试这个:

 var vm = from b in Book
          join c in Comment on b.Id equals c.BookId into d
          where b.UserId == userid 
          orderby b.DateTime
          select new {
                      OrderedDate = from item in d
                                    orderby item.DateTime
                                    select item
                     }

或UNION的另一种方法

var vm = (from a in book
         where a.UserId == userid
         select new { a.DateTime })
         .Union
         (from b in Comment
         where (x=> x.Book.Any(y=>y.UserId == userid))
         select new { b.DateTime })
         .Select(c => new { c.DateTime }).OrderBy(d => d.DateTime);

答案 1 :(得分:1)

如果我理解正确,您希望在一个网格中显示两个具有不同列的表的记录。

要显示哪些列?

让我们说它们是ID,TYPE(书籍条目或评论条目)和DT(日期时间)。

var result = (from b in _context.Books
              where b.UserId = userid
              select new {b.Id Id, "BOOK" Type, b.DateTime DT})
            .Union(
              (from c in _context.Comments
               where c.UserId = userid
               select new {c.Id Id, "COMMENT" Type, c.DateTime DT})
            ).OrderByDescending(x => x.DT);

答案 2 :(得分:1)

这就是我的表现,。

public class BookAndComment
        {
            public DateTime DateTime { get; set; }
            public Book Book { get; set; }
            public Comment Comment { get; set; }
        }

和查询

var orderedBooksAndComments = = books.Where(book => book.UserId == userId).Select(book =>
            new BookAndComment
            {
                DateTime = book.DateTime,
                Book = book
            }).Union(comments.Where(comment => comment.UserId == userId).Select(comment =>
                new BookAndComment
                {
                    DateTime = comment.DateTime,
                    Comment = comment
                }
            )).OrderByDescending(bookAndComment => bookAndComment.DateTime).ToList();

foreach (var item in orderedBooksAndComments)
{ 
if(item.Book!=null)
{
// Do something

}else
{
var comment = item.Comment;
// comment should not be null here. 
// Do something.
}
}

答案 3 :(得分:1)

这是适合您的解决方案。基本上我采用了对数据进行客观化并创建linq查询的想法,该查询从每个列表创建对象列表并根据DateTime对它们进行排序。通过重写ToString()方法,打印列表的内容变得非常简单:

public class Book
{
    public const string className = "Book";
    public string Id { get; set; }

    public string Name { get; set; }

    public string UserId { get; set; }

    public DateTime DateTime { get; set; }

    public override string ToString()
    {
        return $"Book:    Id: {Id.PadRight(7)} - Name: {Name.PadRight(14)} - DateTime: {DateTime}";
    }

}

public class Comment
{
    public string Id { get; set; }

    public string BookId { get; set; }

    public string UserId { get; set; }

    public string Content { get; set; }

    public DateTime DateTime { get; set; }

    public override string ToString()
    {
        return $"Comment: Id: {Id.PadRight(7)} - Content: {Content.PadRight(11)} - DateTime: {DateTime}";
    }

}

class Program
{
    static void Main()
    {
        try
        {
            string userid = "User1";

            var books = new List<Book>();
            books.Add(new Book { Id = "B1", Name = "Book1", UserId = "User1", DateTime = new DateTime(2016, 11, 16, 11, 15, 00) });
            books.Add(new Book { Id = "B2", Name = "Book2", UserId = "User1", DateTime = new DateTime(2016, 11, 16, 12, 15, 00) });
            books.Add(new Book { Id = "B3", Name = "Book3", UserId = "User2", DateTime = new DateTime(2016, 11, 16, 10, 15, 00) });

            var comments = new List<Comment>();
            comments.Add(new Comment { Id = "c1", BookId = "B3", UserId = "User1", Content = "cmt1", DateTime = new DateTime(2016, 11, 16, 11, 17, 00) });
            comments.Add(new Comment { Id = "c2", BookId = "B1", UserId = "User1", Content = "cmt2", DateTime = new DateTime(2016, 11, 16, 11, 16, 00) });
            var test = (from b in books
                        where b.UserId == userid
                        select (object)b).Concat
                        (from c in comments
                        where c.UserId == userid
                        select (object)c).OrderBy(x => x.GetType() == typeof(Book)?((Book)x).DateTime:((Comment)x).DateTime);
            foreach(var o in test)
            {
                Console.WriteLine(o);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }
}

更多的想法,使用通用对象总是让我感到不安,并想出了一个更好的解决方案。通过使用具有公共属性的基类以及从中派生的书籍和注释类,您创建的列表可以包含书籍或注释,并且可以按任何基类属性对其进行过滤和排序:

public class Item
{
    public string Id { get; set; }
    public string UserId { get; set; }
    public DateTime DateTime { get; set; }
}
public class Book:Item
{
    public string Name { get; set; }

    public override string ToString()
    {
        return $"Book:    Id: {Id.PadRight(7)} - Name: {Name.PadRight(14)} - DateTime: {DateTime}";
    }

}

public class Comment:Item
{
    public string BookId { get; set; }

    public string Content { get; set; }

    public override string ToString()
    {
        return $"Comment: Id: {Id.PadRight(7)} - Content: {Content.PadRight(11)} - DateTime: {DateTime}";
    }

}

创建过滤和排序列表变得更加简单:

string userid = "User1";

var items = new List<Item>();
items.Add(new Book { Id = "B1", Name = "Book1", UserId = "User1", DateTime = new DateTime(2016, 11, 16, 11, 15, 00) });
items.Add(new Book { Id = "B2", Name = "Book2", UserId = "User1", DateTime = new DateTime(2016, 11, 16, 12, 15, 00) });
items.Add(new Book { Id = "B3", Name = "Book3", UserId = "User2", DateTime = new DateTime(2016, 11, 16, 10, 15, 00) });
items.Add(new Comment { Id = "c1", BookId = "B3", UserId = "User1", Content = "cmt1", DateTime = new DateTime(2016, 11, 16, 11, 17, 00) });
items.Add(new Comment { Id = "c2", BookId = "B1", UserId = "User1", Content = "cmt2", DateTime = new DateTime(2016, 11, 16, 11, 16, 00) });
var test = (from b in items
            where b.UserId == userid
            orderby b.DateTime
            select b);
foreach (var o in test)
{
    Console.WriteLine(o);
}