私はLinqをSqlに使用しており、クラスを生成しないストアドプロシージャを持っています。ストアドプロシージャは、複数のテーブルのデータをフラットファイルの結果セットに描画します。複雑なSQLストアドプロシージャをlinqに変換
返されるデータ量はできるだけ小さくする必要があります.Sql Serverへのラウンドトリップ回数を制限する必要があります。また、ASP.NET MVCの場合と同じように、サーバー側の処理量を制限する必要がありますプロジェクト。
私はLinqをSql Queryに書くことを試みていますが、返されたデータを複製して制限することには苦労しています。これまでのところ、私はフラットファイルを返すが、リストの数を制限することはできないのですが、
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:
- 結果クラスラッパー:
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
- 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
他にも提案がありますか?
私の考えは、なぜこれをしたいのですか? Linq2SQLはSQLを補完するものであり、SQLを補完するものではありません。 – leppie
私が読んだことから、LinqはSQLのテーブルへのマッピングを行いました。私はstored_procをマッピングしようとしましたが、sqlmetalはエラーをスローします。簡単な方法があれば、私はそれをやって喜んでいるでしょう。 – Graeme
sqlmetalのエラーは何ですか? – leppie