2011-02-05 4 views
3
받았다 포인트가 그들이 제출 한 게시물 받았다있다 upvotes, 그들이 제출 한 사건과 의견을 기반으로 사용자 포인트 계산

안녕 메신저 -LINQ, 하나가 아닌 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 개의 별도 db 호출을한다. 내가 이것을 하나 할 수 있을까?

+2

그냥 팁 :'postPoints ?? 0'' 대신'(postPoints.HasValue? postPoints.Value : 0)' –

답변

5

, 당신은 사용할 수 있습니다

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() 
+0

로 단일 SQL 쿼리로 변환됩니까? 번역 할 쿼리를 게시 할 수 있습니까? –

+1

@ 존 : 그렇습니다. –

1

하나의 쉬운 방법은 데이터베이스에서 필요한 모든 쿼리/계산을 수행 한 다음 L2S를 사용하여보기를 쿼리하는 것입니다. 이렇게하면 데이터베이스를 한 번 호출하게됩니다. 우리는 때때로 데이터베이스에 대한 호출을 저장하거나 쿼리에 특별한 힌트가 필요한 경우 (예 : 잠금 힌트 등)이 작업을 수행합니다. 뷰를 사용하는 것은 특별한 도메인 객체 (데이터베이스의 테이블과 1 : 1 관계가없는 객체)를 수화하는 좋은 방법이기도합니다.

+0

내 sql은 정말 나쁘다.이 모든 것을 할 수있는 하나의 sql 쿼리를 만들 수 있습니까? – raklos

+0

데이터베이스 스키마에 대한 추가 정보없이 단일 T-SQL 문을 통해이 작업을 수행 할 수 있는지 여부는 알 수 없습니다. 하지만, 이모, 그건 진짜 문제가 아니에요. 여기서 내가 할 수있는 일은 L2S 문장에 의해 생성되는 T-SQL 문을 포착하는 것입니다. LinqPad와 같은 도구로이 작업을 수행 할 수 있습니다. 그런 다음 생성 된 T-SQL을 가져 와서 뷰를 만들 수 있습니다. –

+0

SQL을 보려면 datacontext의 Log 속성을 Response outputstream –

2

이런 식으로 SQL Server에서 테이블에 가입하고 사용자의 게시물을 선택하는 등의 작업을 모두 수행 한 다음 값만 반환하는 저장 프로 시저를 만드는 것이 좋습니다 너는 필요해.

Linq-to-SQL에서 저장된 proc을 쉽게 호출하여 결과를 얻을 수 있습니다.

당신은 정확한 테이블 구조를 보여주지 못했지만, 아마 뭔가 같은 것 :

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에이 저장 프로 시저를 추가하고 호출 할 수 있어야한다 이 같은 데이터 컨텍스트에 대한 방법, 뭔가 등이 저장된 프로 시저가 :

당신이 정말로 하나의 호출 여전히 쿼리를 작성하는 SQL에 LINQ를 사용하여 필요한 경우
public int GetUserPoints(string userName) 
{ 
    return db.GetUserPoints(userName); 
} 
+0

으로 설정해야합니다. return (int) db.GetUserPoints (userName) .SingleOrDefault(). Column1; 더 좋은 방법이 있습니까? 그것은 완벽하게 작동한다는 것 외에도 – raklos

+0

@raklos : 스토어드 프로 시저의 마지막 줄을'RETURN @PostPoints + @EventPoints + (@CommentPoints/5)'로 변경하면 저장된 proc을 호출하고 그냥 돌아올 수 있어야합니다 반환 값은'int' –

관련 문제