我的示例包含2个表Book
和Comment
。
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
收集的所有comments
和userid
。但是,如何通过.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);
}
}
}
}
结果:
答案 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);
}