public class Chat
{
public string ChatID { get; set; }
[Required]
public ICollection<Message> Messages { get; set; }
}
public class Message
{
public string MessageID { get; set; }
public DateTime Time { get; set; }
[Required]
public Chat Chat { get; set; }
}
我如何加载聊天列表,其中包含最新(仅限)(按Message.Time
排序})消息,每个请求只有ICollection<Message> Messages
导航属性到DB? EF Core中没有包含条件(chat.messages.last())
答案 0 :(得分:0)
这适用于EF6,在EF Core中不确定
您可以按照@CodeNotFound的想法进行修改,然后 可能 仍可以单独往返数据库,前提是您只对聊天感兴趣有消息
var chatInfos = db.Chats
.Where(chat => ...) // filter chats if you need to
.SelectMany(chat =>
// INNER JOIN with Messages, ORDER by Time, SELECT TOP 1
chat.Messages.OrderByDescending(m => m.Time).Take(1),
// Explicitly load Chat, LastMessage and no more than that
(chat, msg) => new
{
Chat = chat,
LastMessage = msg
})
// Materialize!!
// EF will fix-up Chat-Message navigation and will know that LastMessage is in the Chat's messages collection
.ToList()
// Sort again, you have the last message but not the chats ordered by last message
.OrderByDescending(x => x.LastMessage.Time)
// Now you have a list of chats, with last message, sorted by last message time
.ToList();
foreach (var info in chatInfos)
{
var chatEntry = db.Entry(info.Chat);
var messageCollection = chatEntry.Collection(x => x.Messages);
// Tell EF that the collection is loaded
// Though the last query only loaded ONE Message entity via Explicit Loading
messageCollection.IsLoaded = true;
}
// Get the chats, now calls to chat.Messages should not be lazy loaded for these and the collection should contain only one Message
var chats = chatInfos.ConvertAll(x => x.Chat);
我没有测试此代码,但在EF 6上使用类似的代码