我正在使用實體框架4.1與POCOs和DbContext,沒有代理沒有延遲加載。在單個查詢中的實體列表中加載最近的相關實體記錄
我對Entity Framework和LINQ很新,但對於使用它非常簡單,至今印象非常深刻。 我有一些基本的SQL知識,並且先建立了數據庫,然後創建了模型。
我的問題涉及到3個表(我只在什麼是相關左起):
CREATE TABLE [dbo].[Users](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NULL
)
CREATE TABLE [dbo].[UserFriends](
[UserId] [int] NOT NULL,
[FriendId] [int] NOT NULL
)
CREATE TABLE [dbo].[UserStatuses](
[Id] [int] IDENTITY(1,1) NOT NULL,
[UserId] [int] NOT NULL,
[Message] [nvarchar](max) NOT NULL
)
的PK是Usres.Id,UserStatuses.Id,UserFriends.UserId + UserFriends.FriendId。
UserId也是FK給Users.Id。
每個用戶都可以有許多狀態和許多朋友
我希望數據庫結構清晰。
我想要做的是獲得我的朋友和他們最近的狀態的用戶列表。
在SQL中,它看起來像:
SELECT * FROM Users U
OUTER APPLY
(
SELECT TOP 1 *
FROM UserStatuses
WHERE UserId = U.Id
ORDER BY Id DESC
) S
WHERE U.Id IN (SELECT FriendId FROM UserFriends WHERE UserId = 5)
這將讓所有的朋友「5」和他們的最新狀態信息。 我認爲這是最有效的方式(對朋友和用戶進行內部連接,對狀態消息進行外部連接),但這不是問題。
我想這樣做使用實體框架。 我發現如何讓我的朋友列表:
var friends = db.UserFriends.Where(f => f.FriendId.Equals(userId)).Select(f => f.User);
但是,如果我將添加在.include(U => u.UserStatuses)獲得的狀態,我會得到所有的人,我會喜歡只返回最近的一個。
我設法爲了得到它的工作做的唯一的事情就是:
var friends = db.UserFriends.Where(f => f.FriendId.Equals(userId)).Select(f => f.User);
foreach (Model.User friend in friends)
{
db.Entry(friend).Collection(f => f.UserStatuses).Query().OrderByDescending(s => s.Id).Take(1).Load();
}
但是現在的情況是,每個朋友我產生另一個SQL查詢到數據庫中,這似乎是(很)不好的做法。
我該如何在單個查詢中做到這一點?
希望瞭解如何加載最新插入的相關實體的任何建議。
感謝,
謝謝,生成的SQL與我上面粘貼的完全一樣(只是更多的冗長)。 –