2011-11-06 13 views
1


我正在使用實體框架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查詢到數據庫中,這似乎是(很)不好的做法。

我該如何在單個查詢中做到這一點?
希望瞭解如何加載最新插入的相關實體的任何建議。

感謝,

回答

1

只有這樣,在一個數據庫中查詢得到,這是一個預測:

var friendsWithLastStatus = db.UserFriends 
    .Where(f => f.FriendId.Equals(userId)) 
    .Select(f => new 
    { 
     User = f.User, 
     LastStatus = f.User.UserStatuses 
          .OrderByDescending(s => s.Id).FirstOrDefault() 
    }) 
    .ToList(); 

這給你一個列表中的匿名類型的對象,其中每個條目有User屬性和LastStatus財產與該用戶的最新狀態。

您可以伸進如果你喜歡一個名爲類型:

public class UserWithLastStatus 
{ 
    public User User { get; set; } 
    public UserStatus LastStatus { get; set; } 
} 

然後在上面new ...查詢通過new UserWithLastStatus ...替換獲得List<UserWithLastStatus>的結果類型的查詢。

+0

謝謝,生成的SQL與我上面粘貼的完全一樣(只是更多的冗長)。 –

相關問題