2011-01-24 5 views
0

저는 Linq를 Sql로 사용하고 있고 클래스를 생성하지 않는 저장 프로 시저가 있습니다. 저장된 proc은 여러 테이블의 데이터를 플랫 파일 결과 집합으로 그립니다.복잡한 SQL 저장 프로 시저를 linq으로 변환

반환되는 데이터의 양은 가능한 한 작아야하며 Sql 서버로 왕복하는 횟수는 제한되어야하며 ASP.NET MVC의 경우 서버 측 처리량이 제한되어야합니다 계획.

그래서 저는 SQL 쿼리에 Linq를 작성하려고 시도하지만 반환 된 데이터를 복제하고 제한하는 데 어려움을 겪고 있습니다. 지금까지 내가 플랫 파일을 반환하지만, 목록의 수를 제한 할 수없는 오전 수,

SELECT AdShops.shop_id as ID, Users.image_url_75x75, AdShops.Advertised, 
    Shops.shop_name, Shops.title, Shops.num_favorers as hearts, Users.transaction_sold_count as sold, 
    (select sum(L4.num_favorers) from Listings as L4 where L4.shop_id = L.shop_id) as listings_hearts, 
    (select sum(L4.views) from Listings as L4 where L4.shop_id = L.shop_id) as listings_views, 
    L.title AS listing_title, L.price as price, L.listing_id AS listing_id, L.tags, L.materials, L.currency_code, 
    L.url_170x135 as listing_image_url_170x135, L.url AS listing_url, l.views as listing_views, l.num_favorers as listing_hearts 

FROM AdShops INNER JOIN 
    Shops ON AdShops.shop_id = Shops.shop_id INNER JOIN 
    Users ON Shops.user_id = Users.user_id INNER JOIN 
    Listings AS L ON Shops.shop_id = L.shop_id 

WHERE (Shops.is_vacation = 0 AND 
    L.listing_id IN 
    (
     SELECT listing_id 
     FROM (SELECT l2.user_id , l2.listing_id, RowNumber = ROW_NUMBER() OVER (PARTITION BY l2.user_id ORDER BY NEWID()) 
        FROM Listings l2 
          INNER JOIN (
          SELECT user_id 
          FROM Listings 
          GROUP BY 
            user_id 
          HAVING COUNT(*) >= 3 
          ) cnt ON cnt.user_id = l2.user_id 
       ) l2 
     WHERE l2.RowNumber <= 3 and L2.user_id = L.user_id 
    ) 
    ) 
ORDER BY Shops.shop_name 

지금 :

는 여기에 내가 변환 할 노력하고있어 저장된 프로 시저입니다. 나는 붙어 곳은 다음과 같습니다

Dim query As IEnumerable = From x In db.AdShops 
         Join y In (From y1 In db.Shops 
            Where y1.Shop_name Like _Search + "*" AndAlso y1.Is_vacation = False 
            Order By y1.Shop_name 
            Select y1) On y.Shop_id Equals x.shop_id 
         Join z In db.Users On x.user_id Equals z.User_id 
         Join l In db.Listings On l.Shop_id Equals y.Shop_id 
         Select New With { 
          .shop_id = y.Shop_id, 
          .user_id = z.user_id, 
          .listing_id = l.Listing_id 
          } Take 24 ' Fields ommitted for briefity... 

내가 가게 당 3 명 명부의 임의의 집합을 선택하는 가정, 그러나 나는이 작업을 수행하는 방법을 잘 모르겠습니다 람다 식을 사용해야 할 것입니다. 또한 개별 상점에 대한 업체 정보를 나열하기 위해 어딘가에 통합 합계를 추가해야합니다 ...

누구든지 어떤 생각이 있습니까?

UPDATE :

  1. 결과 클래스 래퍼 :

    여기에 내가 찾고 있어요 현재 솔루션의

 
    Public Class NewShops 
     Public Property Shop_id As Integer 
     Public Property listing_id As Integer 
     Public Property tl_listing_hearts As Integer? 
     Public Property tl_listing_views As Integer? 
     Public Property listing_creation As Date 
    End Class 
  1. Linq에 + 코드 :
 
Using db As New Ads.DB(Ads.DB.Conn) 
    Dim query As IEnumerable(Of IGrouping(Of Integer, NewShops)) = 
     (From x In db.AdShops 
     Join y In (From y1 In db.Shops 
        Where (y1.Shop_name Like _Search + "*" AndAlso y1.Is_vacation = False) 
        Select y1 
        Skip ((_Paging.CurrentPage - 1) * _Paging.ItemsPerPage) 
        Take (_Paging.ItemsPerPage)) 
       On y.Shop_id Equals x.shop_id 
     Join z In db.Users On x.user_id Equals z.User_id 
     Join l In db.Listings On l.Shop_id Equals y.Shop_id 
     Join lt In (From l2 In db.Listings _ 
        Group By id = l2.Shop_id Into Hearts = Sum(l2.Num_favorers), Views = Sum(l2.Views), Count() _ 
        Select New NewShops With {.tl_listing_views = Views, 
               .tl_listing_hearts = Hearts, 
               .Shop_id = id}) 
       On lt.Shop_id Equals y.Shop_id 
     Select New NewShops With {.Shop_id = y.Shop_id, 
            .tl_listing_views = lt.tl_listing_views, 
            .tl_listing_hearts = lt.tl_listing_hearts, 
            .listing_creation = l.Creation, 
            .listing_id = l.Listing_id 
            }).GroupBy(Function(s) s.Shop_id).OrderByDescending(Function(s) s(0).tl_listing_views) 

    Dim Shops as New Dictionary(Of String, List(Of NewShops)) 

    For Each item As IEnumerable(Of NewShops) In query 
     Shops.Add(item(0).shop_name, (From i As NewShops In item 
             Order By i.listing_creation Descending 
             Select i Take 3).ToList) 
    Next 
End Using 

누구든지 다른 의견이 있으십니까?

+3

제 생각에는 왜 이것을하고 싶습니까? Linq2SQL은 SQL을 보완하는 것이지 SQL을 보완하기위한 것입니다. – leppie

+0

필자가 읽은 것부터, Linq는 테이블에 SQL 매핑을했다. 그러나 stored_proc 매핑 시도했는데 sqlmetal 오류가 throw됩니다. 더 쉬운 방법이 있다면 나는 그것을 행복하게 할 것입니다. – Graeme

+0

sqlmetal의 오류는 무엇입니까? – leppie

답변

1

SQL과 코드의 모습에서 LINQ 쿼리로 바꾸지 않았을 것입니다. 그것은 단지 논리를 난독 처리하고 아마도 올바른 것으로 만들기 위해 며칠이 걸릴 것입니다.

SQLMetal이 제대로 생성하지 못하면 DataContextExecuteQuery 메서드를 사용하여 이후 항목의 목록을 반환 할 생각이 있습니까?

는 변환하려는 당신의 sproc가 sp_complicated라고, 당신은 현실에서 도피하기 전에 트릭을

Protected Class TheResults 
    Public Property ID as Integer 
    Public Property image_url_75x75 as String 
    '... and so on and so forth for all the returned columns. Be careful with nulls 
End Class 

'then, when you want to use it 

Using db As New Ads.DB(Ads.DB.Conn) 
    dim results = db.ExecuteQuery(Of TheResults)("exec sp_complicated {0}", _Search) 
End Using 

을해야 다음, 그에게 영향을받지 않습니다 년대처럼, 하나 개의 매개 변수에 뭔가 소요된다고 가정 SQL 주입. L2SQL uses proper SQLParameters, squigglies를 사용하고 문자열을 직접 연결하지 않는 한.

+0

이 정보는 훨씬 쉽게 들립니다. 위의 저장된 proc 파일에 페이징을 어떻게 추가합니까? – Graeme

+0

음, 그게 내가 잘 모르겠다. Row_Number와 몇 가지 매개 변수를 사용한다고 상상해 봅니다. 그러나 저는 _years_에 대한 페이징을하지 않았습니다. 빠른 구글은 대부분의 사람들이 CTE와 Row_Number를 사용한다고 말합니다 - 검색/binging "SQL 서버 스토어드 프로 시저 row_number 페이징"이 좋은 지점이 될 것입니다 –

+0

감사합니다 Dan ... 감사합니다 ... – Graeme

관련 문제