سؤال

أنا أقوم ببناء تطبيق ويب ASP.NET ذو 4 طبقات. الطبقات هي:

  1. طبقة البيانات
  2. طبقة الكيان
  3. طبقة العمل
  4. طبقة واجهة المستخدم

تحتوي طبقة الكيان على فئات نموذج البيانات الخاصة بي وهي مصممة من نموذج بيانات الكيان الخاص بي (ملف EDMX) في Datalayer باستخدام قوالب T4 (POCO). تتم الإشارة إلى طبقة الكيان في جميع الطبقات الأخرى.

تحتوي طبقة البيانات الخاصة بي على فئة تسمى SourceyreePository والتي لها وظيفة مثل ذلك:

public IEnumerable<SourceKey> Get(SourceKey sk)
{
    using (dmc = new DataModelContainer())
    {
        var query = from SourceKey in dmc.SourceKeys
                    select SourceKey;

        if (sk.sourceKey1 != null)
        {
            query = from SourceKey in query
                    where SourceKey.sourceKey1 == sk.sourceKey1
                    select SourceKey;
        }

        return query;
    }
}

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

تم التخلص من مثيل ObjectContext ولم يعد من الممكن استخدامه للعمليات التي تتطلب اتصالًا.

أنا متأكد من أن هذا هو أن DatamodelContainer "DMC" تم التخلص منه. كيف يمكنني إرجاع هذا الكائن الذي لا يطاق من طبقة البيانات الخاصة بي بحيث لا يعتمد على كائن كائن ، ولكن فقط على Datamodel؟

هل هناك طريقة للحد من التحميل كسول لتحدث فقط في طبقة البيانات؟

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

المحلول

query يتم تقييمه كسول بحيث لا يتم إعادة توزيع البيانات من قاعدة البيانات حتى تعددها.

اذا فعلت:

return query.ToList();

سوف تجبر على تنفيذ الاستعلام وتجنب المشكلة.

تتلقى رسالة الخطأ لأنه عندما يعدد المتصل المجموعة ، فإن ObjectContext (dmc) تم التخلص منه بالفعل بفضل الخاص بك using بند (وهو أمر جيد - التخلص من الموارد المتعلقة بقاعدة البيانات في وقت مبكر!)

يحرر

في المنشور الأصلي الذي استخدمته AsEnumerable() الذي اعتقدت أنه كان صحيحًا - حتى حاولت مؤخرًا استخدامه في هذا الموقف بالضبط بنفسي. AsEnumerable() فقط يجعل تحويل نوع وقت الترجمة - لا يعتمد. لإجبار الاستعلام على تعداده ، يجب حفظه في أ List أو مجموعة أخرى.

نصائح أخرى

يمكنك استدعاء بعض الطرق على query كائن ، على سبيل المثال

return query.AsEnumerable();

يجب أن تتأكد من تنفيذ الاستعلام ، وبالتالي التأكد من أنك لا تحتاج إلى سياق الكائن لاحقًا.

لا تستخدم

return query.AsEnumerable();

استعمال

return query.ToArray();

قبل التخلص من سياقك.

إرجاع ASENUMABILE لن ينفذ foreach حتى يتم الرجوع إلى الكائن. يضمن تحويله إلى صفيف تنفيذ Foreach قبل التخلص من الكائن. يمكنك وضع سياقك في كتلة (شيء يجب عليك فعله) ثم.

في رأيي ، هذا السيناريو ليس له صلة بـ Asenumerable () أو asqueryable (). جرب هذا؛

 public IEnumerable<SourceKey> Get(SourceKey sk, DataModelContainer dmc) {    

    var query = from SourceKey in dmc.SourceKeys
                select SourceKey;

    if (sk.sourceKey1 != null)
    {
        query = from SourceKey in query
                where SourceKey.sourceKey1 == sk.sourceKey1
                select SourceKey;
    }

    return query;

}

ويجب أن تحصل على هذه الخاصية

using (dmc = new DataModelContainer()) {
 // GET
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top