2

お時間をいただきありがとうございます。

私たちは CSLA 3.5.1 を使用していますが、最終的には、この問題は CSLA とはあまり関係がないかもしれません。

私の会社は、よくあるモデリング エラーへの道のりを長い道のりを歩んできましたが、ついにそれに直面しなければなりません。問題を明確にするために、以下のドメイン オブジェクトを簡略化しました。

そのように定義された 3 つのクラスがあります。

クラス Person : ビジネスベース

クラス受講生:人

クラスの先生:人

ORM に NHibernate を使用しており、PersonID を派生キーとして使用して、マッピング (Person、Student、および Teacher テーブルがあります) で Student クラスと Teacher クラスが Person のサブクラスに結合されています。

問題は、ご想像のとおり、学生が教師にもなり得る状況になったことです。現在のオブジェクト モデルとデータ モデルでは、すでに教師である生徒を追加しようとすると、またはその逆の場合に主キー違反が発生します。

質問 1: この状況を防ぐために、新しいレコードを保存する前に、ビジネス オブジェクトに対して実行できる CSLA マジックはありますか?

そうでなければ...

この問題を調査する中で、私はそれを解決するための 2 つの提案を見てきました。1 つ目は、継承よりも構成を優先することです。私の理解では、これは Student と Teacher がそれぞれ Person プロパティを含むことを意味します。

質問 2: これを機能させるには、Student テーブルと Teacher テーブルに Person テーブルへの外部キーが必要であると想定するのは正しいですか? 私はこの解決策を完全には理解していないと思います。何らかのガイダンスが必要です。

2 番目の解決策は、生徒と教師を、特定の人物が果たす役割として考えることです。私が見たところによると、Person クラスには Roles コレクションが必要であり、リンク テーブル (PersonRoles?) を使用して Student テーブルと Teacher テーブルのレコードを Person にマップします。

質問 3: Role 基本クラスと PersonRoles テーブルはどのように見えますか? Student と Teacher のサブクラスには、適切なプロパティだけが含まれていると思います。これは正しいです?

解決策について何か意見はありますか?誰かがウェブ上で肉付けされた例を見つけることができれば、私はそれを見てみたい.

ありがとう、

意思。

4

3 に答える 3

1

アプリケーションがサポートする必要がある使用シナリオをサポートするモデルを設計する必要があります。

次の仮定を使用します。

  • Person は、クラスの教師および/または生徒になることができます。

モデル

Person : BusinessBase<Person> 単一の ID をモデル化します。

PersonList : BusinessListBase<PersonList, Person> システム内のすべての ID のリスト。

Student : BusinessBase<Student> 生徒用の追加のプロパティと動作を持つ Person を集約します。

StudentList : BusinessListBase<StudentList, Student> すべての学生のリスト。

Teacher : BusinessBase<Teacher> 教師の追加のプロパティと動作を持つ Person を集約します。

TeacherList : BusinessBase<TeacherList, Teacher> すべての教師のリスト。

Class : BusinessBase<Class> 単一のクラスをモデル化する

ClassTeacher : BusinessBase<ClassTeacher> クラスの先生をモデルにしています。

ClassTeacherList : BusinessListBase<ClassTeacherList, ClassTeacher> クラスの教師のリスト。

ClassStudent : BusinessBase<ClassStudent> クラスの学生をモデル化します。

ClassStudentList : BusinessListBase<ClassStudentList, ClassStudent> クラスの生徒のリスト。

このようなモデルでは、同じクラスであっても Person が同時に Student と Teacher になることを止めることはできません。

各クラス (またはそのような DTO) は、NHibernate を使用して関連するデータ テーブルにマップできます。たとえば、をフェッチするStudent場合、Student テーブルと Person テーブルからデータをフェッチできます。

于 2011-03-30T11:20:36.937 に答える
1

キースの答えを詳しく説明するために
-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は、より行動的な(通常は承認)ものです。つまり、通常、ロールを使用してデータを保存することはありません。したがって、このアプローチは、生徒と教師の唯一の違いが実行を許可されているアクションである場合にのみお勧めします。
その場合でも、将来の柔軟性があまりないため、お勧めしません。

全体として、合成ソリューションが最善の策だと思います。

于 2011-03-29T12:46:30.797 に答える
1

質問 1: 私の知る限りではありません。それは大したことではありません。私は CSLA を使用していませんが、これは NHibernate の問題であり、NHibernate で解決する必要があると考えています。

質問 2: はい、概念的に。Person には 0 対 1 の Student と 0 対 1 の Teacher が含まれますが、すべての Student と Teacher には Person 参照が必要です。これには 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 はこのオブジェクト グラフの頂点です。People、Students、または Teachers を取得できますが、変更を保存するときは、常に Person を保存すると、その Person の子ロールも保持されます。

于 2011-03-28T20:57:41.370 に答える