سؤال

أحاول اكتشاف شيء مع رمز EF4 فقط. إذا استخدمت TPH وأردت تغيير الشخص المحفوظ إلى المدرب أو العكس ، فكيف يمكنني تحقيق ذلك. فصول POCO الخاصة بي:

    public class Person
{
    public int PersonId { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }
}
public class Instructor : Person
{
    public DateTime? HireDate { get; set; }
}

public class Student : Person
{
    public DateTime? EnrollmentDate { get; set; }
}

public class Admin : Person
{
    public DateTime? AdminDate { get; set; }
}

public class PersonConfiguration : EntityConfiguration<Person>
{
    public PersonConfiguration()
    {
        this.HasKey(u => u.PersonId).Property(u => u.PersonId).IsIdentity();
        MapHierarchy()
            .Case<Person>(p => new
            {
                p.PersonId,
                p.FirstName,
                p.LastName,                    
                PersonCategory = 0
            })
            .Case<Instructor>(i => new
            {

                i.HireDate,
                PersonCategory = 1
            })
            .Case<Student>(s => new
            {
                s.EnrollmentDate,
                PersonCategory = 2
            })
            .Case<Admin>(a => new
            {

                a.AdminDate,
                PersonCategory = 3
            }).ToTable("Person");

    }
}

لنقول أن لدي شخص:

var person1 = new Person { FirstName = "Bayram", LastName = "Celik" };
context.People.Add(person1);
context.SaveChanges();

في وقت لاحق أريد أن أجعل هذا الشخص مسؤول. كيف يمكنني إنجاز هذا.

var person = context.People.FirstOrDefault();
Admin test = person as Admin; // wont work

سيؤدي التالية إلى تغيير عمود Hiredate ولكن فئة Personcatefore Personalator الخاصة بي لا تزال 0. لذلك لا يزال ليس نوع المسؤول بقدر مخاوف EF

Admin admin = new Admin();
admin.PersonId = person.PersonId;
admin.AdminDate = DateTime.Now;

context.ObjectContext.Detach(person);
context.People.Attach(admin);
var customerEntry = context.ObjectContext.ObjectStateManager.GetObjectStateEntry(admin);
customerEntry.SetModified();
customerEntry.SetModifiedProperty("AdminDate");
هل كانت مفيدة؟

المحلول

لا يمكنك تغيير نوع الكائن. لا يمكنك القيام بذلك في C#، ولا تعمل EF حول هذا. هذا مبدأ أساسي لـ OOP.

بدلاً من ذلك ، تحتاج إلى إصلاح تصميم النموذج الخاص بك. كما كتبت بعض الوقت:

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

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