سؤال

لدي فئة مستودع يلتف LinQ على سياق بيانات SQL. فئة المستودع هي فئة خط الأعمال التي تحتوي على جميع منطق البيانات (والتخزين المؤقت ومثلج).

إليك V1 الخاص بي من واجهة Repo الخاصة بي.

public interface ILocationRepository
{
    IList<Location> FindAll();
    IList<Location> FindForState(State state);
    IList<Location> FindForPostCode(string postCode);
}

ولكن للتعامل مع الترحيل للحصول على findall، أنا مناقشة ما إذا كانت لا تعرض IQueryable أم لاu003CILocation> بدلا من إيليست لتبسيط واجهة الظروف مثل الترحيل.

ما هي إيجابيات وسلبيات لفضح Iqueryable من Repo البيانات؟

أي مساعدة موضع تقدير كبير.

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

المحلول

الايجابيات؛ القدرة على التأليف:

  • يمكن للمتصلين إضافة مرشحات
  • يمكن للمتصلين إضافة الترحيل
  • يمكن للمتصلين إضافة الفرز
  • إلخ

السلبيات؛ عدم الاستقرار:

  • مستودع الخاص بك لم تعد وحدة لا يمكن اختبارها بشكل صحيح؛ لا يمكنك الاعتماد على A: تعمل، ب: ماذا او ما نعم هو كذلك؛
    • يمكن للمتصل إضافة وظيفة غير قابلة للترجمة (أي عدم رسم خرائط TSQL؛ فواصل في وقت التشغيل)
    • يمكن للمتصل إضافة عامل تصفية / فرز يجعلها تؤدي مثل كلب
  • منذ المتصلين نتوقع IQueryable<T> لتكون غير قابلة للتأمر، فإنها تحكم في تطبيقات غير قابلة للتأمر - أو يجبرك على كتابة مزود الاستعلام الخاص بك
  • هذا يعني أنك لا تستطيع تحسين / الملف الشخصي DAL

للاستقرار، لقد اتخذت ل ليس الكشف IQueryable<T> أو Expression<...> على مستودعاتي. هذا يعني أنني أعرف كيف يتصرف المستودع، ويمكن أن تستخدم الطبقات العليا من السخرية دون القلق "هل يدعم المستودع الفعلي هذا؟" (إجبار اختبارات التكامل).

ما زلت أستخدم IQueryable<T> إلخ في داخل المستودع - ولكن ليس على الحدود. أنا نشرت بعض المزيد من الأفكار حول هذا الموضوع هنا. وبعد من السهل وضع معلمات الترحيل على واجهة المستودع. يمكنك حتى استخدام طرق التمديد (على الواجهة) لإضافة اختياري معلمات الترحيل، بحيث تحتوي الفئات الخرسانية فقط على 1 طريقة لتنفيذها، ولكن قد يكون هناك 2 أو 3 حمولة زائدة متاحة للمتصل.

نصائح أخرى

كما ذكر عن طريق الإجابة السابقة، تعريض Iqueryable يمنح الوصول إلى المتصلين للعب مع iqueryable نفسه، وهو أو يمكن أن يصبح خطيرا.

المسؤولية الأولى لمنطق الأعمال في مجال الأعمال هي الحفاظ على سلامة قاعدة البيانات الخاصة بك.

يمكنك الاستمرار في تعريض Ilist ويمكن تغيير المعلمات الخاصة بك على النحو التالي، وهذه هي الطريقة التي نفعلها ...

public interface ILocationRepository
{
    IList<Location> FindAll(int start, int size);
    IList<Location> FindForState(State state, int start, int size);
    IList<Location> FindForPostCode(string postCode, int start, int size);
}

إذا الحجم == -1 ثم إرجاع الكل ...

طريقة بديلة...

إذا كنت لا تزال ترغب في العودة IQueryable، فيمكنك إرجاع Iqueryable قائمة داخل وظائفك .. على سبيل المثال ...

public class MyRepository
{
    IQueryable<Location> FindAll()
    {
        List<Location> myLocations = ....;
        return myLocations.AsQueryable<Location>;
        // here Query can only be applied on this
        // subset, not directly to the database
    }
}

تتمتع الطريقة الأولى بميزة على الذاكرة، لأنك ستعود بيانات أقل بدلا من ذلك.

أوصي باستخدام ienumerable. بدلا من الأول قائمة, ، مع ذلك سيكون لديك المزيد من المرونة.

وبهذه الطريقة، ستتمكن من الوصول إليها من DB فقط هذا الجزء من البيانات التي ستستخدمها حقا دون عمل إضافي في مستودعك.

عينة:

// Repository
public interface IRepository
{
    IEnumerable<Location> GetLocations();
}

// Controller
public ActionResult Locations(int? page)
{
    return View(repository.GetLocations().AsPagination(page ?? 1, 10);
}

وهو نظيفة للغاية وبسيطة.

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