إطار الكيان في تطبيق N -Layered - Lazy Loading مقابل أنماط التحميل المتحمسة

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

سؤال

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

لدي تطبيق N-layered: طبقة العرض التقديمي ، طبقة منطق الأعمال ، طبقة النموذج. لنفترض أن البساطة تحتوي على طلبي ، في طبقة العرض التقديمي ، وهو نموذج يسمح للمستخدم بالبحث عن عميل. الآن يقوم المستخدم بملء المرشحات من خلال واجهة المستخدم وينقر على الزر. يحدث شيء ما ويصل الطلب إلى طبقة العرض إلى طريقة مثل CustomerSearch(CustomerFilter myFilter). هذه الطبقة المنطقية التجارية هذه تبقيها بسيطة: تنشئ استعلامًا على النموذج وتعود إلى نتائج.

الآن السؤال: كيف تواجه مشكلة تحميل البيانات؟ أعني أن طبقة منطق العمل لا تعرف أن هذه الطريقة المعينة سيتم الاحتجاج بها فقط بهذا النموذج. لذلك أعتقد أنه لا يعرف ما إذا كان نموذج الطلب يحتاج فقط إلى عودة كائنات العميل أو كائنات العميل مع كيانات الطلب المرتبطة.

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

(from c in ctx.CustomerSet
where c.Name.Contains(strQry) select c).ToList();

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

كيف يمكنك مقدمة هذا الطلب؟

إليكم أفضل فكرة (على ما أظن) منذ الآن. أود أن أسمع منك: لا تنشئ طريقة Corperningearch في BLL الاستعلام مباشرةً ولكنها تمر عبر أساليب تمديد خاصة تشكل الكائنات مثل:

private ObjectQuery<Customer> SearchCustomers(this ObjectQuery<Customer> qry, CustomerFilter myFilter)

و

private ObjectQuery<Customer> IncludeOrders(this ObjectQuery<Customer> qry)

لكن هذا لا يقنعني لأنه يبدو معقدًا للغاية.

شكرا ، ماركو

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

المحلول

فكر في الانتقال إلى DTO للواجهة بين طبقة العرض التقديمي وطبقة العمل ، انظر على سبيل المثال:- http://msdn.microsoft.com/en-us/magazine/ee236638.aspx

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

تبدو خطتك الحالية مقترنة بإحكام بين طبقة العرض وطبقة البيانات.

نصائح أخرى

أوافق على التعليق من HightechRider في إشارة إلى استخدام DTOs ، ومع ذلك لديك سؤال صالح فيما يتعلق بكيانات الأعمال.

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

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

public class Editable
{
    //.......initialize this, other properties/methods....

    public bool CanEdit<TRet>(Expression<Func<Dto, TRet>> property)
    {
        //do something to determine can edit
        return true;
    }

    public bool Update<TRet>(Expression<Func<Dto, TRet>> property, TRet updatedValue)
    {
        if (CanEdit(property))
        {
            //set the value on the property of the DTO (somehow)
            return true;
        }
        return false;
    }

    public Dto ValueOf { get; private set;}
}

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

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

public class PageData
{
    public int PageNum;
    public int TotalNumberPages;
    public IEnumerable<Dto> DataSet;
}

public class BL
{
    public PageData GetPagedData(int pageNum, int itemsPerPage, Expression<Func<Dto, bool>> whereClause)
    {
        var dataCt = dataContext.Dtos.Where(whereClause).Count();
        var dataSet = dataContext.Dtos.Where(whereClause).Skip(pageNum * itemsPerPage).Take(itemsPerPage);

        var ret = new PageData
                        { 
                          //init this
                        };

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