2011-02-05 49 views
3

喜IM計算基礎上,他們已經收到了他們提交的職位,有收到點upvotes,他們已經提交了事件和評論的用戶點 -LINQ to SQL中,進行一次DB調用,而不是三個

public int GetUserPoints(string userName) 
{ 
    int? postPoints = db.Posts.Where(p => p.Aspnet_User.UserName == userName).Sum(b => (int?)b.UpVotes); 
    int? eventPoints = db.Events.Where(p => p.Aspnet_User.UserName == userName).Sum(b => (int?)b.UpVotes); 
    int? commentPoints = db.Comments.Where(p => p.Aspnet_User.UserName == userName).Sum(c => (int?)c.UpVotes - (int?)c.DownVotes); 

    return (postPoints.HasValue ? postPoints.Value : 0) + (eventPoints.HasValue ? eventPoints.Value : 0) + (commentPoints.HasValue ? commentPoints.Value/5 : 0); 
} 

我做了3個獨立的數據庫調用來實現這一點。我可以在一個這樣做嗎?

+2

只是一個提示:使用`postPoints ?? 0'而不是`(postPoints.HasValue?postPoints.Value:0)` – 2011-02-05 11:54:31

回答

5

如果你真的只需要一個電話,仍然使用LINQ to SQL來構建查詢,你可以使用:

var sum = (from p in db.Posts where p.Aspnet_User.UserName == userName select p.UpVotes).Concat 
       (from e in db.Events where e.Aspnet_User.UserName == userName select e.UpVotes).Concat 
       (from c in db.Comments where c.Aspnet_User.UserName == userName select (c.UpVotes - c.DownVotes)).Sum() 
1

一個簡單的方法是在您的數據庫中創建一個視圖,執行所有您需要的查詢/計算,然後使用L2S查詢視圖。這將導致您的數據庫的一次調用。我們有時會這樣做,以節省對數據庫的調用,和/或如果我們的查詢有特殊需求(如鎖提示等)。使用視圖也是保護特殊域對象(與數據庫中的表不具有1:1關係的對象)的好方法。

+0

我的sql非常糟糕,我可以創建一個sql查詢,可以做到這一切嗎? – raklos 2011-02-05 12:24:45

+0

我真的不知道這是否可以通過單個T-SQL語句來完成,而不需要關於數據庫模式的更多信息。但是,國際海事組織,這不是真正的問題。我在這裏可能要做的是捕獲由您的L2S語句生成的T-SQL語句。你可以用LinqPad這樣的工具來做到這一點。然後,您可以使用生成的T-SQL並在其周圍創建一個View。 – 2011-02-05 12:36:58

+0

要查看sql只需將datacontext上的Log屬性設置爲Response輸出流 – 2011-02-05 13:53:05

2

對於這樣的事情,最好在你的SQL Server上創建一個存儲過程,爲你做所有這些事情(連接表,選擇用戶的帖子等等),然後返回值你需要。

您可以輕鬆地從Linq-to-SQL調用存儲過程並返回結果。

你沒有表現出精確的表結構,但它可能會是這樣的:

CREATE PROCEDURE dbo.GetUserPoints(@UserName VARCHAR(50)) 
AS BEGIN 
    DECLARE @UserID UNIQUEIDENTIIFIER 

    SELECT @UserID = ID FROM dbo.ASPNET_Users WHERE UserName = @UserName 

    DECLARE @PostPoints INT 
    DECLARE @EventPoints INT 
    DECLARE @CommentPoints INT 

    SELECT @PostPoints = SUM(ISNULL(Upvotes, 0)) 
    FROM dbo.Posts WHERE UserID = @UserID 

    SELECT @EventPoints = SUM(ISNULL(Upvotes, 0)) 
    FROM dbo.Events WHERE UserID = @UserID 

    SELECT @CommentPoints = SUM(ISNULL(Upvotes, 0)) - SUM(ISNULL(Downvotes, 0)) 
    FROM dbo.Comments WHERE UserID = @UserID 

    -- updated: using RETURN gives you a method on your Linq context that you can 
    -- easily call like this: 
    -- 
    -- int myUserPoints = dataContext.GetUserPoints(......) 
    -- 
    RETURN @PostPoints + @EventPoints + (@CommentPoints/5) 
END 

,然後添加此存儲過程的LINQ到SQL的DataContext,你應該能夠調用該存儲過程作爲您的數據上下文的方法,像這樣:

public int GetUserPoints(string userName) 
{ 
    return db.GetUserPoints(userName); 
}