سؤال

أنا أبحث عن وسيلة لاسترداد "المحيطة" الصفوف في NHibernate الاستعلام إعطاء المفتاح الأساسي و نوع النظام ؟

E. g.لدي جدول مع إدخالات سجل و أريد أن عرض إدخال المفتاح الأساسي 4242 السابقة 5 إدخالات وكذلك بعد 5 مشاركات أمر من قبل التاريخ (لا توجد علاقة مباشرة بين التاريخ و المفتاح الأساسي).هذا سؤال يجب أن تعود 11 الصفوف في المجموع (طالما نحن لسنا على مقربة من طرفي).

سجل الدخول الجدول يمكن أن تكون ضخمة و استرجاع كل إلى معرفة ذلك غير ممكن.

هل هناك مفهوم مثل عدد الصفوف التي يمكن استخدامها من داخل NHibernate?قاعدة البيانات الأساسية هو إما أن يكون SQlite أو Microsoft SQL Server.

التعديل وأضاف عينة

تخيل البيانات التالية:

Id   Time
4237 10:00
4238 10:00
1236 10:01
1237 10:01
1238 10:02
4239 10:03
4240 10:04
4241 10:04
4242 10:04   <-- requested "center" row
4243 10:04
4244 10:05
4245 10:06
4246 10:07
4247 10:08

عند طلب الدخول مع المفتاح الأساسي 4242 علينا الصفوف 1237, 1238 و 4239 إلى 4247.النظام هو الزمن, Id.

هل من الممكن لاسترداد الإدخالات في استعلام واحد (التي من الواضح أنها يمكن أن تشمل الاستعلامات الفرعية)?الوقت غير فريدة من نوعها العمود حتى عدة مقالات لها نفس القيمة في هذا المثال هو أنه ليس من الممكن تغيير القرار بطريقة يجعلها فريدة من نوعها!

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

المحلول

"ليس هناك علاقة مباشرة بين التاريخ و المفتاح الأساسي" يعني أن المفاتيح الأساسية ليست في ترتيب تسلسلي?

ثم أود أن تفعل ذلك من هذا القبيل:

Item middleItem = Session.Get(id);

IList<Item> previousFiveItems = Session.CreateCriteria((typeof(Item))
  .Add(Expression.Le("Time", middleItem.Time))
  .AddOrder(Order.Desc("Time"))
  .SetMaxResults(5);

IList<Item> nextFiveItems = Session.CreateCriteria((typeof(Item))
  .Add(Expression.Gt("Time", middleItem.Time))
  .AddOrder(Order.Asc("Time"))
  .SetMaxResults(5);

هناك خطر من وجود عدة عناصر مع نفس الوقت.


تحرير

هذا يجب أن تعمل الآن.

Item middleItem = Session.Get(id);

IList<Item> previousFiveItems = Session.CreateCriteria((typeof(Item))
  .Add(Expression.Le("Time", middleItem.Time)) // less or equal
  .Add(Expression.Not(Expression.IdEq(middleItem.id))) // but not the middle
  .AddOrder(Order.Desc("Time"))
  .SetMaxResults(5);

IList<Item> nextFiveItems = Session.CreateCriteria((typeof(Item))
  .Add(Expression.Gt("Time", middleItem.Time))  // greater 
  .AddOrder(Order.Asc("Time"))
  .SetMaxResults(5);

نصائح أخرى

هذا ينبغي أن يكون من السهل نسبيا مع NHibernate معايير API:

List<LogEntry> logEntries = session.CreateCriteria(typeof(LogEntry))
.Add(Expression.InG<int>(Projections.Property("Id"), listOfIds))
.AddOrder(Order.Desc("EntryDate"))
.List<LogEntry>();

هنا listOfIds هو مجرد بقوة كتابة قائمة من الأعداد الصحيحة تمثل هويات الإدخالات التي تريد استرداد (الاعداد الصحيحه 4242-5 خلال 4242+5 ).

بالطبع يمكنك أيضا إضافة Expressions التي تمكنك من استرجاع معرفات أكبر من 4242-5 و أصغر من 4242+5.

ستيفان الحل يعمل بالتأكيد ولكن أفضل طريقة موجودة باستخدام واحد حدد متداخلة الاستعلامات الفرعية:

ICriteria crit = NHibernateSession.CreateCriteria(typeof(Item));

        DetachedCriteria dcMiddleTime =
            DetachedCriteria.For(typeof(Item)).SetProjection(Property.ForName("Time"))
            .Add(Restrictions.Eq("Id", id));

        DetachedCriteria dcAfterTime =
            DetachedCriteria.For(typeof(Item)).SetMaxResults(5).SetProjection(Property.ForName("Id"))
            .Add(Subqueries.PropertyGt("Time", dcMiddleTime));
        DetachedCriteria dcBeforeTime =
            DetachedCriteria.For(typeof(Item)).SetMaxResults(5).SetProjection(Property.ForName("Id"))
                .Add(Subqueries.PropertyLt("Time", dcMiddleTime));

        crit.AddOrder(Order.Asc("Time"));
        crit.Add(Restrictions.Eq("Id", id) || Subqueries.PropertyIn("Id", dcAfterTime) ||
                 Subqueries.PropertyIn("Id", dcBeforeTime));

        return crit.List<Item>();

هذا هو NHibernate 2.0 جملة ولكن الشيء نفسه ينطبق على الإصدارات السابقة حيث بدلا من قيود استخدام التعبير.

لقد اختبرت هذا على اختبار التطبيق يعمل كما هو معلن

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