‫‫‫رابطه یک به یک در NHibernate و Castle ActiveRecord

بین دو Entity می‌توان رابطه یک به یک برقرار کرد. یعنی به ازای یک instance (رکورد) از یکی، فقط و فقط یک instance (رکورد) در دیگری وجود داشته باشد. هر چند که NH این نوع رابطه را نشانه طراحی بد می‌داند، اما دو راه برای پیاده‌سازی آن مهیا کرده است:

۱- روش primary key associations: در این روش هر دو entity از یک primary key مشترک استفاده می‌کنند.

۲- روش unique foreign key associations: در این روش یکی از طرفین رابطه یک ستون اضافی تعریف کرده و آن را به کلید خارجی مرتبط با primary key طرف دیگر رابطه اختصاص می‌دهد.

هر دوی این روش‌ها به تفصیل در مستندات NH توضیح داده شده‌اند. Castle ActiveRecord هم هر دو این روش‌ها را پشتیبانی می‌کند. مستندات خود ActiveRecord فقط روش اول توضیح داده است اما برای پیاده‌سازی روش دوم هم کار چندان سختی نیست
{لینک به مطلب مرتبط در وبلاگ خودم}.

Unique foreign key associations in Castle ActiveRecord

NHibernate have 2 varieties of one-to-one association, primary key associations and unique foreign key associations. Castle ActiveRecord documentation describes just first varity, primary key associations.

But how about second variety, unique foreign key associations? Well, it can be implemented as follow. Please notice sample:

    [ActiveRecord(Lazy = true)]
    public class User : ActiveRecordBase
    {
        [PrimaryKey]
        public virtual long ID { set; get; }

        [Property]
        public virtual string FirstName { set; get; }

        [OneToOne(PropertyRef = “ContainerUser”)]
        public virtual Profile ContainerProfile { set; get; }
    }

    [ActiveRecord(Lazy = true)]
    public class Profile : ActiveRecordBase    {
        [PrimaryKey]
        public virtual long ID { set; get; }

        [Property]
        public virtual string Field1 { set; get; }

        [BelongsTo(“ContainerUser”, Unique = true, NotNull = true)]
        public virtual User ContainerUser { set; get; }
    }

BelongsTo and cascading

BelongsTo is a attribute in Castle ActiveRecord that is used to mark an association as many-to-one. For example consider following class diagram. There is an association between Student and Teacher named ArtStudent. This is a many-to-one association so you must add BelongsTo attribute to Student class as showed in following code snippet.

[ActiveRecord(Lazy = true)]
public class Teacher : ActiveRecordBase
{
    //other properties
}

[ActiveRecord(Lazy = true)]
public class Student : ActiveRecordBase
{
    [BelongsTo("ArtTeacher_ID", Cascade = CascadeEnum.None)]
    public virtual Teacher ArtTeacher { set; get; }

    //other properties
}

As this is an one-way association from Student only, Teacher does not know anything about student so it not necessary to add any association or property to Teacher.

Using Cascade field of BelongsTo attribute you can tell ActiveRecord what to do if any modifications occurs to Student. These modification can be SaveUpdate and/or Delete. Please take attention that means modifications just for Student not Teacher. For example if you have had set cascade mode to CascadeEnum.Delete, whenever the Student is deleted, its associated Teacher will be deleted too, but if a Teacher is deleted, no Student will be deleted.

More documentation about BelongsTo attribute:

1. BelongsToAttribute API Document (Trunk)
2.  BelongsToAttribute API Document (RC1)
3. BelongsToAttribute Class
4. BelongsToAttribute Members
5. CascadeEnum Enumeration