Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# linq到sql,进行一次db调用,而不是三次_C#_.net_Linq To Sql - Fatal编程技术网

C# linq到sql,进行一次db调用,而不是三次

C# linq到sql,进行一次db调用,而不是三次,c#,.net,linq-to-sql,C#,.net,Linq To Sql,Hi im根据用户提交的帖子、事件和评论获得的投票数计算用户积分- 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.

Hi im根据用户提交的帖子、事件和评论获得的投票数计算用户积分-

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次db调用。我可以一次完成吗?

一种简单的方法是在数据库中创建一个视图,该视图执行所有需要的查询/计算,然后使用L2S查询该视图。这将导致对数据库的一次调用。我们有时这样做是为了保存对数据库的调用,和/或如果我们的查询有特殊需要(如锁提示等)。使用视图也是添加特殊域对象(与数据库中的表没有1:1关系的对象)的好方法。

对于类似的情况,最好在SQL Server上创建一个存储过程,为您完成所有这些工作(加入表、选择用户的帖子等等)然后返回所需的值

您可以轻松地从Linq调用存储过程到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);
}

如果您确实只需要一个调用,并且仍然使用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()

提示:使用
postPoints??0
而不是
(postPoints.HasValue?postPoints.Value:0)
我的sql非常糟糕,我可以创建一个sql查询来完成所有这些吗?我真的不知道在没有关于数据库架构的更多信息的情况下,是否可以通过一个t-sql语句来完成。但是,在国际海事组织,这并不是真正的问题。这里我可能要做的是捕获L2S语句生成的T-SQL语句。您可以使用像LinqPad这样的工具来实现这一点。然后,您可以获取生成的T-SQL并围绕它创建一个视图;有更好的方法吗?除此之外,它还能工作perfect@raklos:如果将存储过程中的最后一行更改为
RETURN@PostPoints+@EventPoints+(@CommentPoints/5)
,那么您应该能够调用存储过程,只需返回一个返回值作为
int
,这是否转换为单个SQL查询?你能把它翻译成的问题贴出来吗?