سؤال

عند استخدام Rhino Commons Unitofwork (في UnitofWorkApplication لـ ASP-MVC) ، أود استخدام فئة Rhino Respository الثابتة لإنقاذ كيانات مثل هذا:

Repository<Car>.Save(new Car(Id = 1));

أجد أنه يمكنني بعد ذلك إخراج الكيان مباشرة بعد تلك المكالمة باستخدام:

Car car = Repository<Car>.Get(1);

هذا يعمل بشكل جيد. ومع ذلك ، عندما أستخدم مزود Nhibernate LINQ على وحدات وحيد القرن مثل هذا:

var allCars = (from rep in UnitOfWork.CurrentSession.Linq<Car>()
               select rep).ToList();

أحصل على قائمة فارغة. يبدو أنني يجب أن أتصل بـ unitofwork.current.flush () قبل أن أتمكن من إخراج السيارة من هذا القبيل. لا أفهم السبب ، بالنظر إلى أنه وراء الكواليس ، أفترض أن كلتا الطريقتين الاسترجاعين تستفسر عن نفس الجلسة / وحدة العمل. هل هذا يعني أنه يجب عليك الاتصال بـ unitofwork.current.flush () بعد كل حفظ إلى قاعدة البيانات؟ ألا ينبغي أن يكون Nhibernate قادرًا على العمل عند مسح نفسه؟ أم أنا أسيء فهم شيء ما؟

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

المحلول

حسنًا ، يبدو أنه على الرغم من أن الحصول على استدعاء إلى المستودع يمكنه استخدام ذاكرة التخزين المؤقت للجلسة ، لذلك يمكن "رؤية" السيارة المحفوظة في ذاكرة التخزين المؤقت:

Car car = Repository<Car>.Get(1); // This works because it uses the same session

لا يستخدم استعلام LINQ ذاكرة التخزين المؤقت للجلسة:

var allCars = (from rep in UnitOfWork.CurrentSession.Linq<Car>()               
select rep).ToList(); // Does not work, even if it is in the same code block and even though it uses the same session

لذا فإن أفضل الممارسات هي أي تغييرات في قاعدة البيانات (حفظ ، تحديث ، حذف ، إدراج) يجب أن يتبعها:

UnitOfWork.Session.Flush(), 

أو ملفوفة في:

With.Transaction(delegate{
   // code here
})

أو تزيين طريقتك مع [المعاملة] واستخدم أجهزة الصراف الآلي. سيضمن ذلك أن يبحث استعلامات LINQ اللاحقة في البيانات الحديثة.

نصائح أخرى

عندما تقوم باستدعاء ropository.save ، فأنت تخطر الجلسة التي يحتفظ بها المستودع لتتبع هذا الكائن ومزامنة التغييرات على قاعدة البيانات عند التدفق التالي. حتى تقوم بتنظيف الجلسة ، لا يتم إجراء أي تغييرات على قاعدة البيانات. يصبح الكائن جزءًا من ذاكرة التخزين المؤقت للجلسة ، وبالتالي سيتم إرجاعه بواسطة GET (1).

عندما تقوم بتشغيل استعلام لإلغاء مجموعة ، تستفسر الجلسة من قاعدة البيانات للحصول على النتائج ، ما لم تكن قد قامت بالفعل بتخزين المؤقت هذه النتائج. نظرًا لأنك لم تقم بتحديث قاعدة البيانات بعد ، فإن السيارة التي أضفتها إلى الجلسة لن تكون جزءًا من مجموعة النتائج. (<-ربما غير صحيح) إذا كنت أقرأ الوثائق بشكل صحيح ، يجب إضافة كلا من نتائج الاستعلام و Save () ED إلى ذاكرة التخزين المؤقت للجلسة (المستوى الأول). هذا لا يعني بالضرورة أن querystatement.List() الاستعلامات ذاكرة التخزين المؤقت بعد إضافة نتائج DB ... أواجه صعوبة في لف رأسي حول ما يحدث بالضبط.

جانبا ، أعتقد أنه يمكنك تعيين الجلسة على Autoflush ولكن يجب أن أتحقق من الوثائق.

تحديث:

أعتقد أنني قد أرى ما يحدث هنا. الجلسة الافتراضية FlushMode هو Auto لكن وحيد القرن UnitOfWork.Start() يخلق جلسة مع أ FlushMode ضبط ل Commit, ، مما يعني أن الجلسة لن تنقل تلقائيًا إلا إذا اتصلت بوضوح Flush() أو ارتكاب المعاملة. مع FlushMode من Auto, ، سوف Nhibernate (في بعض الأحيان؟) مسح الجلسة قبل الاستعلام لمنع إرجاع البيانات التي لا معنى لها. إذا كنت على حق ، فإن معاملة DB الخاصة بك تبدو شيئًا مثل:

SELECT * FROM Car

INSERT INTO Car (...) VALUES (...)

عندما يبدو الأمر غامضًا بعض الشيء من الوثائق/المدونات التي قرأتها ... الإجابة الأكثر شيوعًا هي ذلك FlushMode = Auto إنه يطول "أحيانًا" على الرغم من ضمان ذلك Session.Find لن تُرجع البيانات التي لا معنى لها أبدًا. نظرًا لأن Nhibernate LINQ في الواقع يخلق استعلامًا للمعايير ، فقد لا يؤدي ذلك إلى تدفق السيارات (ربما تم إصلاح هذا الآن ... من الصعب معرفة ذلك).

لذلك يبدو لي أنه في حالتك تريد أن تغسل بعد الحفظ لأنك تريد على الفور استرداد نتائج حفظك. في وحدة عمل أصغر حيث كنت تقوم بتحديث الكيانات فقط ، سيكون التزام واحد () على ما يرام. يمكن UnitOfWork.CurrentSession.FlushMode = FlushMode.Auto; سيفعل الخدعة ، لكن حقيقة أن مصنع UOW يحدد بشكل صريح الوضع للالتزام يبدو أنه يشجعك على التفكير حقًا في حدود UOW الخاصة بك.

بفضل Stuart Childs ، أظن أنه محق في أن القضية قد تكون مع مزود Nhibernate LINQ. لست متأكدًا مما يفعله وراء الكواليس ، لكن قد يستخدم جلسة مختلفة ، إذا كان الأمر كذلك فمن المنطقي أنه يتعين عليّ مسح المستودع قبل أن يرى "استعلام LINQ". حان الوقت للنظر من خلال الكود المصدر ، لكن قيل لي إنه سوف يذوب رأسي وهو يحاول فهمه!

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