linq to sql,进行一次db调用,而不是三次

时间:2011-02-05 10:46:45

标签: c# .net linq-to-sql

我正在根据他们收到的已提交帖子,他们提交的活动以及已收到积分的评论收到的用户积分来计算用户积分 -

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次单独的数据库调用来实现此目的。我可以一个人做这个吗?

3 个答案:

答案 0 :(得分: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 :(得分: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-to-SQL DataContext中,您应该能够将该存储过程称为数据上下文中的方法,如下所示:

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

答案 2 :(得分:1)

一种简单的方法是在数据库中创建一个视图,用于执行所需的所有查询/计算,然后使用L2S查询视图。这将导致对您的数据库的单次调用。我们偶尔这样做是为了节省对数据库的调用,和/或我们的查询是否有特殊需求(如锁定提示等...)。使用视图也是一种很好的方法来保护特殊域对象(与数据库中的表没有1:1关系的对象)。