[英]Grouping by when id can be in column 1 or 2
On my website, members can send messages to each other. 在我的网站上,成员可以相互发送消息。 Here is my Message class :
这是我的Message类:
public partial class Message
{
public System.Guid Id { get; set; }
public System.DateTime DateMsg { get; set; }
public string SenderId { get; set; }
public string ReceiverId { get; set; }
public string Text { get; set; }
}
I'd like to do a query that get the last message for each opened discussion. 我想进行查询,以获取每次打开的讨论的最新消息。 Since I have no "discussion id", I can't do "group by discussionId" and then select the first one in each group.
由于我没有“讨论ID”,因此我无法进行“ group by DiscussionId”,然后选择每个组中的第一个。 How could I do ?
我该怎么办?
public IEnumerable<Message> Get_DiscussionsFor(string userId)
{
List<Message> list;
using (var context = new ModelContainer())
{
IQueryable<Message> dbQuery = context.Set<Message>();
list = dbQuery
.AsNoTracking()
.Where(m => m.SenderId.Equals(userId) || m.ReceiverId.Equals(userId))
.OrderByDescending(m => m.DateMsg)
.ToList<Message>();
}
return list;
}
Well, this might work, although it won't be fast. 好吧,这可能会奏效,尽管不会很快。
Here's the first part of your query: 这是查询的第一部分:
var list1 = dbQuery
.AsNoTracking()
.Where(m => m.SenderId.Equals(userId) || m.ReceiverId.Equals(userId));
I am going to create another query, that creates an anonymous type encapsulating the message and the ID of the other user. 我将创建另一个查询,该查询将创建一个匿名类型,将消息和其他用户的ID封装起来。
var senderFirst = list1
.Where(m => m.SenderId.Equals(userId))
.Select(
m => {
Message = m,
OtherUser = m.ReceiverId
});
I'm creating another one, this time for the ones where the user we want is the receiver, and the Other User is the Sender: 我正在创建另一个,这次是我们想要的用户是接收者,另一个用户是发送者的用户:
var receiverFirst = list1
.Where(m => m.ReceiverId.Equals(userId))
.Select(
m => {
Message = m,
OtherUser = m.SenderId,
});
I am now concatenating them. 我现在将它们串联起来。 I can do this because they have exactly the same properties with the same types and same names: behind the scenes, they're the same anonymous type.
我之所以这样做,是因为它们具有完全相同的属性,相同的类型和相同的名称:在后台,它们是相同的匿名类型。
var list2 = senderFirst.Concat(receiverFirst);
As a result, each message involving the user you want will appear with the other user identified as OtherUser
. 结果,每条涉及您想要的用户的消息将与标识为
OtherUser
的其他用户一起出现。 Note that we haven't changed the Message
object at all: it's still there, with the right values for SenderId
and ReceiverId
. 请注意,我们根本没有更改
Message
对象:它仍然存在,并具有SenderId
和ReceiverId
的正确值。 We just wrapped it in another object, with additional metadata. 我们只是将它包装在带有附加元数据的另一个对象中。
You said that any message involving a given two users is in the same discussion. 您说过,涉及给定两个用户的任何消息都在同一讨论中。 So, we can now simulate grouping by discussion by grouping by the
OtherUser
: 因此,我们现在可以通过讨论通过
OtherUser
的分组来模拟分组:
var list3 = list2.GroupBy(m => m.OtherUser);
So now we have grouped messages. 现在,我们对消息进行了分组。 You can now sort each group and select the final message.
现在,您可以对每个组进行排序并选择最终消息。
var list4 = list3
.Select(g => g.OrderByDescending(m => m.Message.DateMsg).First());
And now you have your List<Message>
, because your Message
object is still in there, ready to be sprung from encapsulation: 现在,您有了
List<Message>
,因为您的Message
对象仍在其中,可以从封装中弹出:
var list = list4
.Select(m => m.Message)
.ToList();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.