NHibernate الترحيل مع SQL Server
-
22-07-2019 - |
سؤال
عند استخدام أساليب 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 الاستعلام وحدد المطلوب فقط الصفوف.