وحدة العمل لعمليات الخام غير تافهة لمستودعات متعددة

StackOverflow https://stackoverflow.com/questions/1822179

  •  10-07-2019
  •  | 
  •  

سؤال

ولقد رأيت وحدة من نمط العمل تنفيذها مع شيء من هذا القبيل البرمجية التالية:

    private HashSet<object> _newEntities = new HashSet<object>();
    private HashSet<object> _updatedEntities = new HashSet<object>();
    private HashSet<object> _deletedEntities = new HashSet<object>();

وبعد ذلك هناك طرق لإضافة الكيانات إلى كل من هذه HashSets.

في الالتزام UnitOfWork يخلق بعض المثال مخطط لكل كيان ويدعو إدراج، تحديث، حذف الأساليب من بعض مخطط وهمي.

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

UnitOfWork ouw = new UnitOfWork();
uow.Start();

ARepository arep = new ARepository();
BRepository brep = new BRepository(); 

arep.DoSomeNonSimpleUpdateHere();
brep.DoSomeNonSimpleDeleteHere();

uow.Commit();

والآن فشل نهج ثلاثة HashSet-لأنني ثم أتمكن من تسجيل A و B الكيانات فقط لإدراج، تحديث، حذف عمليات لكنني بحاجة إلى تلك العمليات الجمركية الآن.

وهكذا يبدو أن لا أستطيع أن <م> دائما كومة من عمليات مستودع ثم نفذ كل منهم مع UnitOfWork.Commit();

وكيفية حل هذه المشكلة؟ الفكرة الأولى هي - I يمكن تخزين عناوين وسائل

arep.DoSomeNonSimpleUpdateHere();
brep.DoSomeNonSimpleDeleteHere(); 

في المثال UOW وتنفيذها على uow.Commit() ولكن بعد ذلك أنا أيضا لتخزين كافة معلمات الأسلوب. هذا يبدو معقدا.

والفكرة الأخرى هي لجعل مستودعات تماما UOW على علم: في DoSomeNonSimpleUpdateHere يمكنني كشف أن هناك UOW تشغيل ولذا فإنني لا يؤدون DoSomeNonSimpleUpdateHere لكن حفظ المعلمات عملية وحالة "انتظار" في بعض كومة مثيل مستودع (من الواضح أنني لا يمكن حفظ كل شيء في UOW لUOW يجب أن لا تعتمد على تطبيقات مستودع محددة). وبعد ذلك تسجيل مستودع تشارك في المقام UOW. عندما يدعو UOW Commit، فإنه يفتح صفقة، ويدعو بعض الشيء مثل فلوش () لكل مستودع معلقة. الآن كل وسيلة من مستودع يحتاج الى بعض الاشياء للكشف عن UOW وعملية تأجيل لCommit() في وقت لاحق.

ولذا فإن السؤال القصير هو - ما هي أسهل طريقة لتسجيل جميع التغييرات المعلقة في مستودعات متعددة في UOW ثم Commit() كل منهم في عملية واحدة

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

المحلول

ويبدو أن حتى التحديثات معقدة يمكن تقسيمها إلى سلسلة من التعديلات على واحد أو أكثر DomainObjects. داعيا DoSomeNonSimpleUpdateHere () قد تعديل العديد DomainObjects مختلفة، الأمر الذي من شأنه أن يؤدي المكالمات الموافق UnitOfWork.registerDirty (DomainObject) لكل كائن. في نموذج التعليمات البرمجية أدناه، لقد حل محل الدعوة إلى DoSomeNonSimpleUpdateHere مع رمز التي تزيل المستخدمين غير نشط من النظام.

UnitOfWork uow = GetSession().GetUnitOfWork();
uow.Start();

UserRepository repository = new UserRespository();
UserList users = repository.GetAllUsers();

foreach (User user in users)
{
  if (!user.IsActive())
    users.Remove( user );
}

uow.Commit();

إذا كنت تشعر بالقلق إزاء الحاجة إلى تكرار عبر جميع المستخدمين، وهنا هو نهج بديل يستخدم كائن معايير للحد من عدد من المستخدمين انسحبت من قاعدة البيانات.

UnitOfWork uow = GetSession().GetUnitOfWork();
uow.Start();

Repository repository = new UserRespository();
Criteria inactiveUsersCriteria = new Criteria();
inactiveUsersCriteria.equal( User.ACTIVATED, 0 );
UserList inactiveUsers = repository.GetMatching( inactiveUsersCriteria );
inactiveUsers.RemoveAll();

uow.Commit();
سوف

وطرق UserList.Remove وUserList.RemoveAll يخطر UnitOfWork من كل مستخدم إزالتها. عندما يتم استدعاء UnitOfWork.Commit ()، فإنه سيتم حذف كل مستخدم وجدت في _deletedEntities لها. هذا النهج يسمح لك لخلق رمز معقد بشكل تعسفي دون الحاجة إلى كتابة الاستفسارات SQL لكل حالة خاصة. عن طريق تحديثات الدفعي سوف يكون من المفيد هنا، منذ UnitOfWork سوف تضطر إلى تنفيذ عبارات الحذف متعددة بدلا من عبارة واحدة فقط لجميع المستخدمين غير نشط.

نصائح أخرى

والحقيقة أن لديك هذه المشكلة تشير إلى أن كنت لا تستخدم نمط مستودع على هذا النحو، ولكن شيئا أشبه بوابات بيانات الجدول متعددة. عموما، هو مستودع للتحميل وحفظ جذر الكلي. على هذا النحو، عند حفظ كيان، طبقة استمرار الخاص يحفظ كل التغييرات في الرسم البياني الكائن الذي الكلي الجذر المثال المنشأة.

إذا، في التعليمات البرمجية، لديك تقريبا "مستودع" واحد في جدول واحد (أو الكيان)، وربما كنت بالفعل باستخدام بوابة بيانات الجدول أو كائن نقل البيانات. في هذه الحالة، وربما كنت بحاجة إلى وسيلة لتمرير في اشارة الى المعاملات النشطة (أو وحدة العمل) في كل طريقة حفظ ().

في كتاب إيفانز DDD من ذلك فهو يقترح ترك السيطرة المعاملات إلى العميل مستودع، وأود أن نتفق على انها ليست ممارسة جيدة، على الرغم من أنه قد يكون من الصعب تجنب إذا كنت فعلا باستخدام نمط الجدول بوابة البيانات.

وأخيرا وجدت هذا واحد:

http://www.goeleven.com/Blog/82

والمؤلف لا يحل المشكلة باستخدام ثلاث قوائم لتحديث / إدراج / حذف، لكنه لا تخزن كيانات هناك. يتم تخزين المندوبين مستودع بدلا من ذلك والمعلمات الخاصة بهم. هكذا الالتزام المكالمات المؤلف كل مندوب مسجل. مع هذا النهج أتمكن من تسجيل حتى بعض الأساليب مستودع معقدة وبالتالي تجنب استخدام TableDataGateway منفصل.

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