2011-08-03 29 views
6

QueryOver <> sözdizimini kullanarak aşağıdaki SQL deyimini nasıl yazabilirim? NHibernate QueryOver <> - AltQuery üzerinde toplama işlevi

SELECT COUNT(*) FROM (
    SELECT FirstName,LastName 
    FROM People 
    GROUP BY FirstName, LastName 
    ) as sub_t 

Ben iç sorgu bugüne kadar çalışan var:

var q = _session.QueryOver<Person>() 
    .SelectList(l => l 
     .SelectGroup(x => x.FirstName) 
     .SelectGroup(x => x.LastName)); 

Ama alt sorguda bu sarın ve bir sıra bunun dışında saymak nasıl hiçbir fikrim yok. Bu yapılabilir mi?

Ne yazık ki RDBMS lehim (MsSqlCe40Dialect), COUNT DISTINCT özelliğini desteklemiyor; bu nedenle SelectCountDistinct() işlevini kullanmanın yararı yok.

cevap

0

IQueryOver ürününün RowCount özelliğini kullanmanız mümkün mü? Şunun gibi:

var totalRows = _session.QueryOver<Person>() 
.SelectList(l => l 
    .SelectGroup(x => x.FirstName) 
    .SelectGroup(x => x.LastName)).RowCount(); 
+1

Ne yazık ki GROUP BY önerinizde korunmuyor, SqlCe4 ve SQL Server 2008'de test ettim. Oluşturulan sorgu, her iki durumda da "SELECT count (*) y0_ FROM [People] this_" şeklindedir. – twerq

1

Tamam, QueryOver kullanarak behing nedenleri bilmiyorum ama böyle bir şey yapacağını, sana aradığınızı size verecektir düşünüyorum:

Session.CreateCriteria<Person>() 
       .SetProjection(
       Projections.ProjectionList() 
        .Add(Projections.GroupProperty("FirstName"))) 
        .Add(Projections.GroupProperty("LastName"))) 
       .List<Person>().Count(); 

Umarım bu yardımcı olur ...

+0

Ne yazık ki bu istenen SQL'i üretmez - tüm kayıt listesi (muazzam olabilir), sayılmadan önce .NET koduna yüklenir. – twerq

1

QueryOver'a aşina değilim, ancak bu tür bir sayım için bir alt sorgu mümkün olmadığında yararlı olabilir diye düşündüğümde aşağıdaki toplama işlevini kullandım. Daha önce farkında olmadığım sorunları da ben de paylaştım.

Not: Orta veri miktarları yaklaşık 10x daha yavaştır.

Agrega yöntem özel durumlarda

benzer kombinasyon isimleri "Joe Smith" "Joes Mith" (Devraldı ~ kümenizdeki değildir) vs

için

SELECT 
COUNT(DISTINCT FirstName+LastName) 
FROM People 

Barındırmasaydı

SELECT COUNT(DISTINCT FirstName+'~'+LastName) FROM People 

nulls (As varsaymaktadır ^,

SELECT 
COUNT(DISTINCT IsNull(FirstName,'^')+'~'+IsNull(LastName,'^')) 
FROM People 

boşluk Firar) kümenizdeki değil RTRIM

SELECT 
COUNT(DISTINCT IsNull(RTrim(FirstName),'^')+'~'+IsNull(Rtrim(LastName),'^')) 
FROM People 

By Kıyaslama AMD verilerin (80k satır tek Dört Çekirdekli)

Grubuna içsel görünüyor

80-100ms - Alt Sorgu Yöntemini Çalıştırma (bkz. OP)

800-1200ms - distinc ile toplama yöntemi t, özel durumlar için uzlaşmak çok fark edilir bir fark yaratıyor gibi görünmüyor.