Нужен совет по моделированию предметной области - надеюсь, общий сценарий - PullRequest
2 голосов
/ 28 марта 2011

и заранее спасибо за ваше время.

Мы используем CSLA 3.5.1, хотя, в конечном счете, эта проблема может не иметь большого отношения к CSLA.

Моя компания ушладолгий путь к распространенной ошибке моделирования и, наконец, приходится сталкиваться с ней.Я упростил доменные объекты ниже, чтобы прояснить проблему:

У нас есть 3 класса, определенных следующим образом:

класс Person: BusinessBase

класс Student: Person

Учитель класса: Person

Мы используем NHibernate для нашего ORM, а классы Student и Teacher объединены в подклассы Person в наших отображениях (у нас есть таблицы Person, Student и Teacher) с использованием PersonIDкак производный ключ.

Проблема, как вы, возможно, ожидали, заключается в том, что теперь у нас есть ситуация, когда студент также может быть учителем.В соответствии с текущими объектами и моделями данных это вызывает нарушение первичного ключа, когда мы пытаемся добавить ученика, который уже является учителем, или наоборот.

Вопрос первый: Есть ли какая-либо магия CSLA, которую я могу выполнить набизнес-объект перед сохранением новой записи, чтобы предотвратить эту ситуацию?

Если нет ...

При исследовании этой проблемы я видел два предложения по ее решению: во-первых, в пользу композициипо наследству.Насколько я понимаю, это означает, что каждый ученик и учитель будут содержать свойство Person.

Вопрос второй: для того, чтобы это сработало, правильно ли предположить, что для таблиц ученика и учителя потребуется внешний ключ вПерсональный стол?Я полагаю, что у меня нет полного понимания этого решения, и мне хотелось бы получить какое-то руководство.

Второе решение заключается в том, чтобы рассматривать ученика и учителя как роли, которые играет данный человек.Из того, что я видел, классу Person понадобится коллекция ролей, а таблица связей (PersonRoles?) Используется для сопоставления записей в таблицах ученика и учителя с персоной.

Вопрос (ы) Три: Как выглядят базовый класс Role и таблица PersonRoles?Я полагаю, что подклассы ученика и учителя будут просто содержать их соответствующие свойства.Это правильно?

Есть мнения по поводу решения?Если кто-нибудь сможет найти в Интернете конкретный пример, я бы хотел его увидеть.

Спасибо,

Будет.

Ответы [ 3 ]

1 голос
/ 29 марта 2011

просто чтобы уточнить ответ Кита-
q2.Стоит добавить, что теперь ваша объектная модель (классы) будет выглядеть примерно так:

    public class Student
{
    public IEnumberable<Class> ClassesIAttend {get; set}
    ...
}

public class Teacher
{
    public IEnumberable<Class> ClassesITeach {get; set;}
    ...
}

public class Person : BussinesBase
{
    //either of these can be null
    private Student studentPart;
    private Teacher teacherPart;

    public bool IsTeacher()
    {
        return teacherPart != null;
    }
}   

q3.Роли, AFAIK, это скорее поведенческая (обычно авторизационная) вещь.Смысл - вы обычно не используете роли для хранения данных.поэтому такой подход был бы вам полезен только в том случае, если единственными различиями между учеником и учителем являются действия, которые им разрешено выполнять.
Даже в этом случае я бы рекомендовал против него, поскольку он не оставляет вам большой гибкостина будущее.

В общем, я думаю, что композиционное решение - ваш лучший выбор.

1 голос
/ 30 марта 2011

Вы должны разработать модель для поддержки сценариев использования, которые должно поддерживать ваше приложение.

Со следующими допущениями:

  • Человек может быть учителем и / или учеником в классе.

Модель

Person : BusinessBase<Person> Моделирует одну личность.

PersonList : BusinessListBase<PersonList, Person> Список всех личностей в системе.

Student : BusinessBase<Student> Агрегирует человека с дополнительными свойствами и поведением для ученика.

StudentList : BusinessListBase<StudentList, Student> Список всех студентов.

Teacher : BusinessBase<Teacher> Объединяет человека с дополнительными свойствами и поведением для учителя.

TeacherList : BusinessBase<TeacherList, Teacher> Список всех учителей.

Class : BusinessBase<Class> Модели одного класса

ClassTeacher : BusinessBase<ClassTeacher> Модели учитель класса.

ClassTeacherList : BusinessListBase<ClassTeacherList, ClassTeacher> Список учителей класса.

ClassStudent : BusinessBase<ClassStudent> Моделирует ученика в классе.

ClassStudentList : BusinessListBase<ClassStudentList, ClassStudent> Список учеников класса.

С такой моделью нет препятствий для того, чтобы Человек одновременно был учеником и учителем даже в одном классе.

Каждый класс (или DTO для таких) может быть сопоставлен с соответствующими таблицами данных с помощью NHibernate. Например, при извлечении Student вы можете получать данные из таблиц Student и Person.

1 голос
/ 29 марта 2011

Вопрос 1: Насколько мне известно. Это не много говорит; Я не использовал CSLA, но я думаю, что это вещь NHibernate, и ее нужно решить с помощью NHibernate.

Вопрос 2: Да, концептуально. Человек имеет от нуля до одного ученика и от нуля до одного учителя, но все ученики и учителя требуют справки о личности. Для этого я использую Fluent NHibernate, поэтому вам придется искать эквивалентный синтаксис HBM, но:

public class PersonMap:ClassMap<Person>
{
    public PersonMap()
    {
        Table("Person");
        Id(x=>Id).Column("PersonID");
        References(x=>x.Student).KeyColumn("StudentID")
            Nullable().Cascade.All();
        References(x=>x.Teacher).KeyColumn("TeacherID")
            Nullable.Cascade.All();
    }
}


public class TeacherMap:ClassMap<Teacher>
{
    public TeacherMap()
    {
        Table("Teacher");
        Id(x=>Id).Column("TeacherID");
        References(x=>x.Person).KeyColumn("PersonID")
            .Not.Nullable().Cascade.None();        
    }
}

public class StudentMap:ClassMap<Student>
{
    public StudentMap()
    {
        Table("Student");
        Id(x=>Id).Column("StudentID");
        References(x=>x.Person).KeyColumn("PersonID")
            .Not.Nullable().Cascade.None();        
    }
}

Теперь Person - вершина графа этого объекта; Вы можете извлекать людей, студентов или учителей, но при сохранении изменений всегда сохраняйте человека, и дочерние роли этого человека также будут сохраняться.

...