Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

LINQ ke SQL Ambil tanpa Loncat Penyebab Beberapa Pernyataan SQL

Pertama - beberapa alasan untuk bug Ambil.

Jika Anda Ambil saja , penerjemah kueri hanya menggunakan top. Top10 tidak akan memberikan jawaban yang benar jika kardinalitas rusak dengan bergabung dalam koleksi anak. Jadi penerjemah kueri tidak bergabung dalam koleksi anak (sebaliknya meminta untuk anak-anak).

Jika Anda Lewati dan Ambil , lalu penerjemah kueri memulai dengan beberapa logika RowNumber di atas baris induk... nomor baris ini membiarkannya mengambil 10 induk, meskipun itu benar-benar 50 catatan karena setiap induk memiliki 5 anak.

Jika Anda Lewati(0) dan Ambil , Lewati dihapus sebagai non-operasi oleh penerjemah - sama seperti Anda tidak pernah mengatakan Lewati.

Ini akan menjadi lompatan konseptual yang sulit dari tempat Anda berada (memanggil Lewati dan Ambil) ke "solusi sederhana". Apa yang perlu kita lakukan - adalah memaksa terjemahan terjadi pada titik di mana penerjemah tidak dapat menghapus Skip(0) sebagai non-operasi. Kita perlu menelepon Skip, dan memberikan nomor yang dilewati di lain waktu.

DataClasses1DataContext myDC = new DataClasses1DataContext();
  //setting up log so we can see what's going on
myDC.Log = Console.Out;

  //hierarchical query - not important
var query = myDC.Options.Select(option => new{
  ID = option.ParentID,
  Others = myDC.Options.Select(option2 => new{
    ID = option2.ParentID
  })
});
  //request translation of the query!  Important!
var compQuery = System.Data.Linq.CompiledQuery
  .Compile<DataClasses1DataContext, int, int, System.Collections.IEnumerable>
  ( (dc, skip, take) => query.Skip(skip).Take(take) );

  //now run the query and specify that 0 rows are to be skipped.
compQuery.Invoke(myDC, 0, 10);

Ini menghasilkan kueri berikut:

SELECT [t1].[ParentID], [t2].[ParentID] AS [ParentID2], (
    SELECT COUNT(*)
    FROM [dbo].[Option] AS [t3]
    ) AS [value]
FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY [t0].[ID]) AS [ROW_NUMBER], [t0].[ParentID]
    FROM [dbo].[Option] AS [t0]
    ) AS [t1]
LEFT OUTER JOIN [dbo].[Option] AS [t2] ON 1=1 
WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p1 + @p2
ORDER BY [t1].[ROW_NUMBER], [t2].[ID]
-- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [0]
-- @p1: Input Int (Size = 0; Prec = 0; Scale = 0) [0]
-- @p2: Input Int (Size = 0; Prec = 0; Scale = 0) [10]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.30729.1

Dan di sinilah kita menang!

WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p1 + @p2


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tidak dapat memasukkan nilai eksplisit untuk kolom identitas dalam tabel 'tabel' ketika IDENTITY_INSERT disetel ke OFF

  2. Tambahkan batasan unik ke kombinasi dua kolom

  3. Apa batasan SQL Server Compact? (Atau - bagaimana cara memilih database untuk digunakan pada platform MS?)

  4. Mendapatkan data dengan rangkaian karakter UTF-8 dari server MSSQL menggunakan ekstensi PHP FreeTDS

  5. Memindahkan Database SQL Server ke Cloud