سؤال

آمل أن يكون العنوان والنص التالي واضحين ، لست على دراية بالمصطلحات الصحيحة ، لذا يرجى تصحيح لي إذا حصلت على أي خطأ. أنا أستخدم LINQ ORM لأول مرة وأتساءل عن كيفية معالجة ما يلي.

قل لدي طاولتان DB:

User
----
Id
Name


Phone
-----
Id
UserId
Model

ينتج مولد LINQ Code مجموعة من فئات الكيانات.

أكتب بعد ذلك فصولي وواجهاتها التي تلتف هذه فئات LINQ:

class DatabaseUser : IUser
{
    public DatabaseUser(User user)
    {
        _user = user;
    }

    public Guid Id 
    {
        get { return _user.Id; } 
    }

    ... etc
}

حتى الان جيدة جدا.

الآن من السهل العثور على هواتف المستخدمين من Phones.Where(p => p.User = user) ولكن من المؤكد أنه لا ينبغي أن يحتاج كومبو واجهة برمجة التطبيقات إلى كتابة استعلامات LINQ الخاصة بهم للوصول إلى البيانات ، لذلك يجب أن ألف هذا الاستعلام في وظيفة أو خاصية في مكان ما.

لذا فإن السؤال هو ، في هذا المثال ، هل ستضيف خاصية هواتف إلى iuser أم لا؟

بمعنى آخر ، إذا كانت الواجهة الخاصة بي هي نمذجة كائنات قاعدة البيانات الخاصة بي على وجه التحديد (في هذه الحالة ، لا تنتمي الهواتف إلى iuser) ، أم أنها في الواقع تقدم مجموعة من الوظائف والخصائص المرتبطة بمفاهيمي (في هذه الحالة يفعل)؟

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

كانت فكرتي الأولى هي استخدام أساليب التمديد ولكن في الواقع لا يعمل في هذه الحالة.

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

المحلول

لقد واجهت بعض التجارب الفظيعة التي تحاول تجريد كيانات LinqToSQL وراء الواجهات. لقد كان منذ فترة ، ولكن من الذاكرة كانت المشكلة الرئيسية هي أنها تكسر الجمعيات تمامًا. على سبيل المثال ، إذا كان لديك ملف Customer -> Order العلاقة ، ينتهي بك الأمر إلى تعريضها ك ICustomer, ، مع مجموعة من IOrderS ، وهذا يعني ذلك Customer يجب أن تفعل بعض التعيينات المحرجة لإلقاء مجموعة داخلية من Order كائنات IOrderس.

ثم عليك أن تفترض أنه عندما IOrder يتم تمريرها مرة أخرى ، بحيث يمكننا إلقاءها على Order. وإلا فإن LinqToSQL لا يمكنه التعامل معها ، ولكن بعد ذلك يهزم نقطة وجود الواجهة هناك في المقام الأول.

أوصي بشدة بأن لا تحاول تجريد فصول الكيان أكثر من اللازم ، لا يضع LinqToSQL أي سحر حقيقي فيها ، ويتعامل DataContext مع دورة حياة الثبات ، لذلك يظلون قابلين للاختبار.

الجوانب التي سأتطلع إلى الاختباء خلف الواجهة هي التفاعلات مع DataContext ، على سبيل المثال باستخدام فئات على غرار المستودع:

public interface IPhoneRepository 
{
    IEnumerable<Phone> GetPhonesForUser(User user);
}

public class L2SPhoneRepository : IPhoneRepository
{
    private readonly MyDataContext context;

    public L2SPhoneRepository(MyDataContext context)
    {
        this.context = context;
    }

    public IEnumerable<Phone> GetPhonesForUser(User user)
    {
        return context.Phones.Where(p => p.User == user);
    }
}

نصائح أخرى

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

يجب عليك إضافة خاصية الهواتف إلى iuser وجعلها قابلة للبطولة ، لذلك بالنسبة للمستخدم الذي ليس لديه هاتف ، سيكون فارغًا.

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

فيما يلي قائمة لطيفة من تطبيق ABT N-Tier في ASP.NET

http://imar.spaanjaars.com/quickdocid.aspx؟quickdoc=416

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

إذا كانت واجهة برمجة التطبيقات الخاصة بك ستستهلكها أشخاص آخرين ، فيجب أن تكون متماسكة وسهلة الاستخدام ولا تشوش من خلال الأشياء التي لا يحتاج المستهلك إلى معرفتها. إذا كنت أتعامل مع المستخدمين وهواتفهم ، فأنا لا أريد حقًا معرفته عن مجموعات بيانات DataContexts أو (UGH).

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

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