سؤال

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

في سياق هذا لا يبدو أن يكون .AddToEmployer البند (فقط ، AddObject أو AddToBaseEntity).

إذا كنت تستخدم AddObject("Employer", NewEmployer) وأحصل على رسالة الخطأ التالية:

عمليات اسم 'DataEntities.رب' لا يمكن العثور عليها.

إذا كنت تستخدم AddToBaseEntity(NewEmployer) أحصل على رسالة خطأ من:

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

فاتني خطوة في إعداد الميراث ؟ هل هناك طريقة محددة لحفظ الأشياء التي هي وراثة ؟ ما الخطأ الذي فعلته ؟ أعتقد أن القضية الأساسية هي أنه يجب أن يكون AddToEmployer, ماذا يجب أن أفعل للحصول على هذا مكشوف ؟ يبدو من الغريب أن ذلك ليس خيارا منذ أستطيع أن أرى صاحب العمل كتابة على جانب العميل و يمكن أن تفعل أشياء مثل:

var NewEmployer = new Employer() التي يبدو أن تشير إلى أن أستطيع أن أرى صاحب العمل نوع جيد.

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

المحلول 3

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

والجداول تمت إعادة: I بناء الجداول بدءا من مجرد ID / الأعمدة الرئيسية وعمود بيانات واحد

وإزالة السيارات تزايد حقول إضافية: كان لي ID-تزايد السيارات على BaseEntity وعلى صاحب العمل. أزلت ID-تزايد السيارات على صاحب العمل، وكان مجرد عمود Employer.BaseEntityID والمفتاح الخارجي إلى BaseEntity.BaseEntityID. (وهذا على ما يبدو كان الجاني، لكنني كنت تحت انطباع سمح هذا)

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

نصائح أخرى

اسمي Phani وأنا أعمل على ADO.NET خدمات البيانات الفريق.

على ResolveName و ResolveType طرق لمساعدتك على تخصيص نوع المعلومات أن العميل يكتب في الحمولة إرسالها إلى الملقم وكيف رد حمولة من الخادم هو تتحقق .

أنها تساعدك على حل أنواع على العميل و هي مفيدة في العديد من السيناريوهات ، بضعة أمثلة هي :

  1. نوع الهرمي من الكيانات على العميل مختلفة بالمقارنة مع الخادم.
  2. أنواع الكيانات التي كشف عنها خدمة الاشتراك في الميراث و تريد العمل مع أنواع مشتقة على العميل.

ResolveName يستخدم لتغيير اسم الكيان الذي وضعنا على السلك عند تقديم طلب إلى الملقم.

النظر في هذا نموذج البيانات :على الخادم

public class Employee {
    public int EmployeeID {get;set;}
    public string EmployeeName {get;set;}
}

public class Manager:Employee {
    public List<int> employeesWhoReportToMe {get;set;}
}

عند استخدام العميل للعمل مع حالات مدير كيان نوع ، عند تقديم التغييرات إلى الخادم ، نتوقع نوع المعلومات تكون موجودة في الحمولة عندما الكيانات المشاركة في الميراث.

context.AddObject("Employees",ManagerInstance ); <-- add manager instance to the employees set.
context.SaveChanges();

ومع ذلك ، عندما يكون العميل يسلسل هذه الحمولة ، فإنه يضع في "الموظف" كنوع اسم وهو ليس ما هو متوقع على الملقم.ومن ثم لديك لتوفير اسم محلل على العميل ،

context.ResolveName = delegate(Type entityType){
    //do what you have to do to resolve the type to the right type of the entity on the server
    return entityType.FullName;
}

نوع محلل يستخدم بنفس الطريقة .

context.ResolveType = delegate(string entitySetName){
    //do what you have to do to convert the entitysetName to a type that the client understands
    return Type.GetType(entitySetName);
}

وكذلك يمكنك فقط الحصول على العلاقات العامة مجموعة الكيان. الفئة الأساسية حتى .AddToBaseEntity هو الحل على هذا النحو.

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

وتأكد من أن لديك مفاتيح خارجية لbaseentity على الكيانات مشتقة وتحديث النموذج الخاص بك.

وليس لديك أصحاب العمل تعريفها بأنها مجموعة كيان، تماما مثل نوع الكيان. وهذا هو الطريق كنت في عداد المفقودين AddToEntity في كائن السياق. هناك دائما كيان واحد المحددة لالتسلسل الهرمي فئة واحدة، في هذه الحالة هو BaseClass مجموعة الكيان.

إذا كنت ترغب في الحصول كيان مجموعة "صاحب العمل" يمكنك محاولة تحرير EDMX الملف يدويا وإضافة مجموعة الكيان الجديد "صاحب العمل"، ثم قم بتعيين "صاحب العمل" نوع الكيان تنتمي إلى أن مجموعة الكيان. لا ينبغي أن يكون من الصعب، وأنا قد فعلت ذلك في الكثير من الأحيان.

ولست متأكدا إذا كان هناك بعض الحلول أكثر انتظاما.

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

وغير متأكدة من الإصدارات السابقة، ولكن الكيان الإطار 4 يتيح لك تفريغ الكائن في سياق ككائن القاعدة، ومن ثم الأرقام إطار من المراجع من جانب الخادم. AddToInheritedObjects وهكذا، فإنك لن تستخدم () (والذي هو مستنكر على أي حال) بل طريقة لObjectSet <> إضافة ().

وإليك مثال فئة المساعد:

public ContextHelper
{
        …
        _context = ModelEntities();

        public T Create<T>() where T : class
        {
            // Create a new context
            _context = new ModelEntities();

            // Create the object using the context (can create outside of context too, FYI)
            T obj = _context.CreateObject<T>();

            // Somewhat kludgy workaround for determining if the object is
            // inherited from the base object or not, and adding it to the context's
            // object list appropriately.    
            if (obj is BaseObject)
            {
                _context.AddObject("BaseObjects", obj);
            }
            else
            {
                ObjectSet<T> set = _context.CreateObjectSet<T>();
                set.AddObject(obj);
            }

            return obj;
        }
        …
}

وهكذا، على افتراض أن يكون لديك ما يلي:

class ObjectOne : BaseObject {}
class ObjectTwo {}

هل يمكن بسهولة إضافة الكيانات إلى السياق:

ContextHelper ch = ContextHelper()
ObjectOne inherited = ch.Create<ObjectOne>();
ObjectTwo toplevel = ch.Create<ObjectTwo>();
…

والتذكر، بطبيعة الحال، أن يجب أن يكون ContextHelper أسلوب عمومي حفظ () الامر الذي يستدعي _context.SaveChanges () - أو أنه يجب أن يكون بطريقة أخرى من دفع يتغير الكائن يصل إلى مخزن البيانات

.

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

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