Rumah > pangkalan data > tutorial mysql > Bagaimana untuk menterjemahkan pertanyaan SQL yang kompleks dengan pelbagai gabungan, tuduhan, dan kiri bergabung ke Linq?

Bagaimana untuk menterjemahkan pertanyaan SQL yang kompleks dengan pelbagai gabungan, tuduhan, dan kiri bergabung ke Linq?

Barbara Streisand
Lepaskan: 2025-01-25 04:18:08
asal
322 orang telah melayarinya

How to Translate a Complex SQL Query with Multiple Joins, Counts, and a Left Join into LINQ?

Tukar pertanyaan SQL yang mengandungi berbilang gabungan, kiraan dan gabungan kiri kepada LINQ

Pertanyaan SQL anda menggunakan berbilang cantuman, cantuman kiri dan fungsi agregat untuk mendapatkan semula data daripada berbilang jadual. Untuk menukar pertanyaan ini kepada LINQ, ikut langkah ini:

  • Tukar subkueri: Ekstrak subkueri ke dalam pembolehubah berasingan melainkan ia merujuk lajur di luar subkueri.
  • Gunakan alias jadual: Gunakan alias jadual sebagai pembolehubah skop dan alias lajur sebagai nama medan jenis tanpa nama.
  • Pengendalian cantuman: Jika menggunakan EF/EF Core, tukar klausa JOIN kepada sifat navigasi. Jika tidak, gunakan objek tanpa nama atau sambung silang dan simulasi WHERE dan LEFT JOIN.
  • Fungsi pengagregatan: Gunakan fungsi agregat LINQ dan bukannya fungsi agregat SQL, seperti COUNT.
  • Distinct(): Gunakan kaedah Distinct() untuk menukar DISTINCT.
  • LEFT JOIN: Gunakan ke dalam, dari dan DefaultIfEmpty() untuk mensimulasikan LEFT JOIN.
  • Jenis tanpa nama: Gunakan jenis tanpa nama untuk menggabungkan berbilang lajur.

Pertanyaan SQL asal:

<code class="language-sql">SELECT DISTINCT c.Id, 
       c.Title, 
       COUNT(v.Id) AS 'Nb_V2',
       COUNT(DISTINCT v.IdUser) AS 'Nb_V1',
       r.cnt AS 'Nb_R'
FROM TABLE_C c
JOIN TABLE_V v on c.Id = v.Id
LEFT JOIN ( 
    SELECT Id, COUNT(*)  AS cnt 
    FROM TABLE_R 
    GROUP BY Id
) r ON c.Id = r.Id
WHERE c.IdUser = '1234'
GROUP BY c.Id, c.Title, r.cnt</code>
Salin selepas log masuk

Penukaran ungkapan pertanyaan LINQ (versi dipertingkatkan):

<code class="language-csharp">var qResult = (from c in dbContext.TABLE_C
              join v in dbContext.TABLE_V on c.Id equals v.Id
              from r in dbContext.TABLE_R.Where(r => r.Id == c.Id).DefaultIfEmpty()
              where c.IdUser == "1234"
              group new { c, v, r } by new { c.Id, c.Title } into grouped
              select new
              {
                  IdC = grouped.Key.Id,
                  Title = grouped.Key.Title,
                  Nb_V2 = grouped.Count(g => g.v.Id != null),
                  Nb_V1 = grouped.Select(g => g.v.IdUser).Distinct().Count(),
                  Nb_R = grouped.Sum(g => (int?)g.r.cnt ?? 0) // 处理r.cnt可能为null的情况
              }).Distinct();</code>
Salin selepas log masuk

Penukaran ungkapan Lambda:

<code class="language-csharp">var ansq = dbContext.TABLE_C
    .Where(c => c.IdUser == "1234")
    .Join(dbContext.TABLE_V, c => c.Id, v => v.Id, (c, v) => new { c, v })
    .GroupJoin(dbContext.TABLE_R, cv => cv.c.Id, r => r.Id, (cv, r) => new { cv, r })
    .SelectMany(x => x.r.DefaultIfEmpty(), (x, r) => new { x.cv.c, x.cv.v, r })
    .GroupBy(x => new { x.c.Id, x.c.Title, cnt = (int?)x.r?.cnt })
    .Select(g => new
    {
        g.Key.Title,
        Nb_V2 = g.Count(x => x.v.Id != null),
        Nb_V1 = g.Select(x => x.v.IdUser).Distinct().Count(),
        Nb_R = g.Key.cnt
    })
    .Distinct();
</code>
Salin selepas log masuk

Pertanyaan LINQ yang dipertingkatkan ini mengendalikan fungsi COUNT dan LEFT JOIN dengan lebih ringkas dan cekap, serta mengelakkan beberapa masalah yang berpotensi dalam kod asal, seperti pertimbangan pelik t.Id > 0 dan kemungkinan r.cnt adalah batal. Ia lebih tepat mencerminkan logik pertanyaan SQL asal. Ambil perhatian bahawa anda perlu melaraskan dbContext.TABLE_C, dbContext.TABLE_V dan dbContext.TABLE_R mengikut konteks pangkalan data dan nama entiti anda.

Atas ialah kandungan terperinci Bagaimana untuk menterjemahkan pertanyaan SQL yang kompleks dengan pelbagai gabungan, tuduhan, dan kiri bergabung ke Linq?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan