سؤال

عند استخدام أساليب SetFirstResult(start) وSetMaxResults(count) لتنفيذ الترحيل لقد لاحظت أن الاستعلام ولدت يفعل سوى select top count * from some_table وأنها لا تأخذ المعلمة start بعين الاعتبار، أو على الأقل ليس على مستوى قاعدة البيانات. ويبدو أنه إذا كنت إرشاد NHibernate لتنفيذ الاستعلام التالي:

var users = session.CreateCriteria<User>()
                   .SetFirstResult(100)
                   .SetMaxResults(5)
                   .List<User>();

105 سجلات سوف عبور بين خادم قاعدة البيانات وتطبيق والتي سوف تأخذ الرعاية لتجريد السجلات 100 الأولى. مع الجداول التي تحتوي على العديد من الصفوف وهذا يمكن أن يكون مشكلة.

ولقد تحققت من أن مع قاعدة بيانات SQLite NHibernate يستفيد من OFFSET وLIMIT الكلمات الرئيسية لتصفية النتائج على مستوى قاعدة البيانات. وأنا أدرك أنه لا يوجد ما يعادلها من الكلمة OFFSET وROWNUM أوراكل في SQL Server 2000 ولكن هناك أي الحل؟ كيف حول SQL Server 2005/2008؟

هل كانت مفيدة؟

المحلول

وT-SQL، والبديل للغة SQL الذي يستخدم Microsoft SQL Server و لايوجد بند limit. لديه معدل select top {...} التي تراها NHibernate الاستفادة من مع SQL Server 2000.

ومع SQL Server 2005، عرضت شركة مايكروسوفت وظيفة Row_Number() over (order by {...}) التي يمكن استخدامها كبديل للبند limit، ويمكنك ان ترى NHibernate الاستفادة من ذلك مع SQL Server 2005/2008.

استعلام عن سكليتي قد تبدو

select c.[ID], c.[Name]
from [Codes] c
where c.[Key] = 'abcdef'
order by c.[Order]
limit 20 offset 40

وحين استعلام مشابهة ل SQL Server 2005 قد تبدو

select c.[ID], c.[Name]
from (
    select c.[ID], c.[Name], c.[Order]
        , [!RowNum] = Row_Number() over (order by c.[Order])
    from [Codes] c
    where c.[Key] = 'abcdef'
) c
where c.[!RowNum] > 40 and c.[!RowNum] <= 60
order by c.[Order]

وأو باستخدام المشتركة الجدول التعبير، قد تبدو وكأنها

with
    [Source] as (
        select c.[ID], c.[Name], c.[Order]
            , [!RowNum] = Row_Number() over (order by c.[Order])
        from [Codes] c
        where c.[Key] = 'abcdef'
    )
select c.[ID], c.[Name]
from [Source] c
where c.[!RowNum] > 40 and c.[!RowNum] <= 60
order by c.[Order]

وهناك طريقة للقيام بذلك في SQL Server 2000 وكذلك

select c.[ID], c.[Name]
from (
    select top 20 c.[ID], c.[Name], c.[Order]
    from (
        select top 60 c.[ID], c.[Name], c.[Order]
        from [Codes] c
        where c.[Key] = 'abcdef'
        order by c.[Order]
    ) c
    order by c.[Order] desc
) c
order by c.[Order]

نصائح أخرى

وNhibernate ذكي بما فيه الكفاية لتحسين الاستعلام. إذا قمت بتحديد 10 الصفوف الأولى أنها سوف تستخدم بيان TOP. إذا قمت بتحديد الصفوف الأولى لا ثم فإنه سيتم استخدام RowNum.

في SQL 2000 ليست هناك وظيفة RowNum، وهذا هو السبب في أنه من المستحيل مع الاستعلام المعتاد لتحديد العدد المطلوب من الصفوف. ل SQL 2000 ما أعرف لمثل هذه الآراء الأمثل استخدمت.

في SQL 2005/2008 الاستعلام وحدد المطلوب فقط الصفوف.


مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top