모든 태그가있는 모든 게시물 선택

.net c# dapper sql sql-server

문제

이 문제에 관해 많은 질문이 있지만 확실한 답변이 없습니다. 특히이 경우 SQL Server를 사용하십시오.

블로그 게시물 및 태그와 관련된 3 개의 테이블이 있습니다. 모든 게시물과 각 게시물 태그를 가져올 쿼리를 실행하고 싶습니다. 태그 ID와 이름이 모두 필요합니다. 결과는 내 C # 클래스로 쉽게 직렬화 할 수 있어야합니다. 나 또한 Dapper.net을 사용하려고 노력하고 있지만 이것이 가장 중요한 부분은 아닙니다.

분명히 많은 웹 사이트에서이 작업을 수행하고 있으며, 최선의 방법과 현실 세계에서 어떻게 수행되어야 하는지를 알고 싶습니다. 모든 게시물을 가져온 다음 각 게시물마다 여러 개의 쿼리를 실행하여 이후에 각 게시물의 태그를 반환합니다. 그러나 확실히 더 좋은 방법이 있어야만합니까?

만약 내가 단지 하나의 게시물을 얻으 려했다면 나는 여러 개의 선택을 쓸 것입니다. 하나는 게시물 용이고 다른 하나는 태그 용입니다. 하지만 나는 모든 게시물을 원한다. 반환되는 각 태그 행에 대한 게시물 정보를 복제하지 않고이 작업을 수행 할 수 있습니까?

각 게시물의 태그가 예를 들어 쉼표로 구분 된 열로 직렬화되는 경우 어떻게 ID와 이름을 모두 얻을 수 있습니까? 문자열을 인코딩 하시겠습니까?

SELECT * FROM dbo.Posts    
SELECT * FROM dbo.Tags
SELECT * FROM dbo.PostTags

Posts
Id  Title       Content
===============================
1   First Post  First Content
3   Second      Second Content

Tags
Id  Name
============
1   C#
2   SQL
3   IIS
4   Steam
5   OpenID

PostTags
PostId  TagId
=============
1       1
1       2
3       3
3       4

다음 쿼리로 테이블을 결합하기 만하면됩니다.

SELECT p.*, t.Name
FROM dbo.Posts p
LEFT JOIN dbo.PostTags pt ON p.id = pt.PostId
LEFT JOIN dbo.Tags t ON t.id = pt.TagId

연결된 각 태그에 대해 게시물 내용을 반복하여 많은 중복 데이터를 제공합니다.

Id  Title       Content         Name
======================================
1   First Post  First Post      C#
1   First Post  First Post      SQL
3   Second Post Second Content  IIS
3   Second Post Second Content  Steam

인기 답변

이것은 순수한 연습 일 뿐이며, 복제 될 데이터의 양이 큰 문제가 아님을 말하면서이 말을 시작하겠습니다. 게시물의 크기가 매우 크고 많은 게시물이 있지만 중복을 피하기 위해 더 많은 이해가 시작됩니다.

또한 C # Linq-to-Sql 또는 Entity Framework를 사용하여 개체 관계가 완성되고 Post 엔터티는 사용자가 액세스 할 수있는 List<Tag> 속성을 갖게됩니다.

그러나 자신의 유형을 롤하려는 경우 하나의 DB 왕복과 데이터 중복이없는 옵션은 포스트 콘텐트가있는 레코드 세트 (2 개의 개별 select 문)를 가져 오는 저장 프로 시저를 작성하는 것입니다. 하나는 태그 내용이 있습니다.

Post 를 나타내는 C # 클래스를 생성하는 것은 매우 간단하고 List<Tag> 가지며 저장된 proc 결과에서 가져옵니다.

Create Procedure GetPostTags
As

-- We will use the GotTags column here to loop through and get tabs later
Declare @Posts Table (
    PostID varchar(50), 
    PostTitle varchar(50), 
    PostContent varchar(50),
    GotTags bit default 0
)

/* Assuming you care about the ID's, this will get you all of 
   the tags without duplicating any post content */
Declare @PostTags Table (
    PostID int,
    TagID int,
    TagName varchar(50)
)

-- Populate posts from the main table
Insert Into @Posts (PostID, PostTitle, PostContent)
Select * From Posts

-- Now loop through and get the tags for each post. 
Declare @CurrentPostID int
Set @CurrentPostID = (Select Top 1 PostID From @Posts Where GotTags = 0)
While @CurrentPostID Is Not Null
    Begin
        Insert Into @PostTags (PostId, TagID, TagName)
        Select pt.postid, pt.tagid, t.name
        From Tags t 
            Join PostTags pt
                On t.id = pt.tagid
        Where pt.postid = @CurrentPostID

        -- Set next loop
        Update @Posts Set GotTags = 1 Where PostID = @CurrentPostID
        Set @CurrentPostID = (Select Top 1 PostID From @Posts Where GotTags = 0)
    End

-- Return 2 recordsets, which are related by the PostID column found in both sets
Select * from @Posts
Select * From @PostTags

문자열을 하나의 문자열로 연결 한 다음 나중에 나누는 것보다이 유형의 솔루션을 선호합니다. 이 방법으로 데이터를보다 쉽게 ​​작업 할 수 있고 C #에서 더 많은 객체 지향적 일 수 있으며 태그를 제거하거나 게시물에서 추가해야하는 경우 태그 ID를 쉽게 추적 할 수 있으므로 필요하지 않습니다. 이미 ID가 있기 때문에 이름으로 태그 또는 일치 항목을 찾으십시오.



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.