流暢なnhibernate - 関係の属性との多対多の関係

私は自分のコードを動作させていますが、多対多の関係を表すためにテーブル/ ddlに2つの余分な列があります。関係の属性(スカラー)を使って~~~~~。

使ってます 1.2.0.712(FluentNHibernate.dll) 3.1.0.4000(NHibernate.dll)

エンティティ:

public partial class Employee
{
    public Employee()
    {
        CommonConstructor();
    }
    private void CommonConstructor()
    {
        this.MyEmployeeToJobTitleMatchLinks = new List();
    }

    public virtual Guid? EmployeeUUID { get; set; }
    public virtual byte[] TheVersionProperty { get; set; }
    public virtual string SSN { get; set; }
    public virtual string LastName { get; set; }
    public virtual string FirstName { get; set; }
    public virtual DateTime CreateDate { get; set; }
    public virtual DateTime HireDate { get; set; }

    public virtual ICollection MyEmployeeToJobTitleMatchLinks { get; set; }
    public virtual void AddJobTitleLink(EmployeeToJobTitleMatchLink link)
    {
        link.TheEmployee = this;
        if (!this.MyEmployeeToJobTitleMatchLinks.Contains(link))
        {
            this.MyEmployeeToJobTitleMatchLinks.Add(link);
        }

        if (!link.TheJobTitle.MyJobTitleToEmployeeMatchLinks.Contains(link))
        {
            link.TheJobTitle.MyJobTitleToEmployeeMatchLinks.Add(link);
        }
    }

    public virtual void RemoveJobTitleLink(EmployeeToJobTitleMatchLink link)
    {
        link.TheEmployee = this;
        if (this.MyEmployeeToJobTitleMatchLinks.Contains(link))
        {
            this.MyEmployeeToJobTitleMatchLinks.Remove(link);
        }

        if (link.TheJobTitle.MyJobTitleToEmployeeMatchLinks.Contains(link))
        {
            link.TheJobTitle.MyJobTitleToEmployeeMatchLinks.Remove(link);
        }
    }
}

public partial class JobTitle
{

    public JobTitle()
    {
        CommonConstructor();
    }
    private void CommonConstructor()
    {
        this.MyJobTitleToEmployeeMatchLinks = new List();
    }

    public virtual Guid? JobTitleUUID { get; set; }
    public virtual byte[] TheVersionProperty { get; set; }
    public virtual string JobTitleName { get; set; }
    public virtual DateTime CreateDate { get; set; }
    public virtual ICollection MyJobTitleToEmployeeMatchLinks { get; set; }
    public virtual void AddEmployeeLink(EmployeeToJobTitleMatchLink link)
    {
        link.TheJobTitle = this;
        if (!this.MyJobTitleToEmployeeMatchLinks.Contains(link))
        {
            this.MyJobTitleToEmployeeMatchLinks.Add(link);
        }

        if (!link.TheEmployee.MyEmployeeToJobTitleMatchLinks.Contains(link))
        {
            link.TheEmployee.MyEmployeeToJobTitleMatchLinks.Add(link);
        }

    }

    public virtual void RemoveEmployeeLink(EmployeeToJobTitleMatchLink link)
    {
        link.TheJobTitle = this;
        if (this.MyJobTitleToEmployeeMatchLinks.Contains(link))
        {
            this.MyJobTitleToEmployeeMatchLinks.Remove(link);
        }

        if (link.TheEmployee.MyEmployeeToJobTitleMatchLinks.Contains(link))
        {
            link.TheEmployee.MyEmployeeToJobTitleMatchLinks.Remove(link);
        }

    }

}

public partial class EmployeeToJobTitleMatchLink
{
    public EmployeeToJobTitleMatchLink()
    {
        //this.Id = Guid.NewGuid(); /* this works in conjuction with    */
    }

    public virtual Guid? LinkSurrogateUUID { get; set; }

    /*  These are "scalar properties of the ~~relationship~~  */
    public virtual int PriorityRank { get; set; }
    public virtual DateTime JobStartedOnDate { get; set; }

    public virtual Employee TheEmployee { get; set; }
    public virtual JobTitle TheJobTitle { get; set; }
}

マッピング:

public class EmployeeMap : ClassMap
{
    public EmployeeMap()
    {
        Id(x => x.EmployeeUUID).GeneratedBy.GuidComb();

        OptimisticLock.Version();
        Version(x => x.TheVersionProperty)
            .Column("MyVersionColumn")
            .Not.Nullable()
            .CustomSqlType("timestamp")
            .Generated.Always();

        Map(x => x.SSN);
        Map(x => x.LastName);
        Map(x => x.FirstName);
        Map(x => x.CreateDate);
        Map(x => x.HireDate);

        HasMany(x => x.MyEmployeeToJobTitleMatchLinks)
            .Inverse()
            .Cascade.All();
    }
}

public class JobTitleMap : ClassMap
{
    public JobTitleMap()
    {
        Id(x => x.JobTitleUUID).GeneratedBy.GuidComb();

        OptimisticLock.Version();
        Version(x => x.TheVersionProperty)
            .Column("MyVersionColumn")
            .Not.Nullable()
            .CustomSqlType("timestamp")
            .Generated.Always();

        Map(x => x.JobTitleName);
        Map(x => x.CreateDate);
        HasMany(x => x.MyJobTitleToEmployeeMatchLinks)
            .Inverse()
            .Cascade.All();
    }
}

public class EmployeeToJobTitleMatchLinkMap : ClassMap
{
    public EmployeeToJobTitleMatchLinkMap()
    {
        Id(x => x.LinkSurrogateUUID).GeneratedBy.GuidComb();
        Map(x => x.PriorityRank);
        Map(x => x.JobStartedOnDate);
        References(x => x.TheEmployee).Column("TheEmployeeUUID").Not.Nullable();/*Bad naming convention with "The", but left here so it can be seen easily in the DDL*/
        References(x => x.TheJobTitle).Column("TheJobTitleUUID").Not.Nullable();/*Bad naming convention with "The", but left here so it can be seen easily in the DDL*/
    }
}

これは問題なく動作しますが、ddlに2つの余分な(NULL可能な)列があります。下のアスタリスク(*)でマークされています。

* [dbo]を選択します。[EmployeeToJobTitleMatchLink] LinkSurrogateUUID
PriorityRank JobStartedOnDate
TheEmployeeUUID
TheJobTitleUUID

* Employee_id
* JobTitle_id

私はこれが「慣例によって」理解されています。 (名前は "_id"で表示されます)。 しかし、私はこれらの列は必要ありません。そして私はカスタマイズされた名前を持つことができる必要があります。 (この模擬例のTheEmployeeUUIDとTheJobTitleUUID。)

私の最終的なゲームは以下を持つことです。

* [dbo]を選択します。[EmployeeToJobTitleMatchLink] LinkSurrogateUUID(UniqueIdentifier、SurrogateKey)
PriorityRank(スカラー、int) JobStartedOnDate(スカラー、日時) TheEmployeeUUID(UniqueIdentifier、FK to dbo.Employee.EmployeeUUID) TheJobTitleUUID(UniqueIdentifier、dbo.JobTitle.JobTitleUUIDに戻るFK)

〜関係の属性は、保持することが非常に重要です。 (このモックアップの例ではPriorityRankとJobStartedOnDate。)

ありがとう。 私は〜とても近いです。

編集:

動作するマッピング:

public class EmployeeMap : ClassMap
{
    public EmployeeMap()
    {
        Id(x => x.EmployeeUUID).GeneratedBy.GuidComb();

        OptimisticLock.Version();
        Version(x => x.TheVersionProperty)
            .Column("MyVersionColumn")
            .Not.Nullable()
            .CustomSqlType("timestamp")
            .Generated.Always();

        Map(x => x.SSN);
        Map(x => x.LastName);
        Map(x => x.FirstName);
        Map(x => x.CreateDate);
        Map(x => x.HireDate);

        HasMany(x => x.MyEmployeeToJobTitleMatchLinks)
            .Inverse()
            .Cascade.All()
            .KeyColumn("TheEmployeeUUID")
            ;

    }
}





public class JobTitleMap : ClassMap
{
    public JobTitleMap()
    {
        Id(x => x.JobTitleUUID).GeneratedBy.GuidComb();

        OptimisticLock.Version();
        Version(x => x.TheVersionProperty)
            .Column("MyVersionColumn")
            .Not.Nullable()
            .CustomSqlType("timestamp")
            .Generated.Always();


        Map(x => x.JobTitleName);
        Map(x => x.CreateDate);
        HasMany(x => x.MyJobTitleToEmployeeMatchLinks)
            .Inverse()
            .Cascade.All()
            .KeyColumn("TheJobTitleUUID")
        ;   

    }
}



public class EmployeeToJobTitleMatchLinkMap : ClassMap
{

    public EmployeeToJobTitleMatchLinkMap()
    {
        Id(x => x.LinkSurrogateUUID).GeneratedBy.GuidComb();
        Map(x => x.PriorityRank);
        Map(x => x.JobStartedOnDate);

        References(x => x.TheEmployee).Column("TheEmployeeUUID").Not.Nullable();/*Bad naming convention with "The", but left here so it can be seen easily in the DDL*/
        References(x => x.TheJobTitle).Column("TheJobTitleUUID").Not.Nullable();/*Bad naming convention with "The", but left here so it can be seen easily in the DDL*/

    }
}

ありがとうナタン!

PS 私がグーグル/ビンゴインをしながら学んだ新しい用語は、

"客観化された関係"

It was in the comments area of this page: LINK1

将来的にページが死ぬ場合、ここにコメントが貼り付けられます:

それは「客観化された関係」(ref: http://www.orm.net )と呼ばれています。 NIAM/ORMは、通常、属性を持つエンティティ自体の関係として定義されています。オブジェクト化された関係は、少なくとも1つのm:n関係を常に形成している。 ( http://weblogs.asp.net/fbouma/ から)

0

1 答え

私はあなたのJobTitleMapとEmplyeeMapの両方にHasManyマッピングの一部としてKeyColumn( "キー名")を追加する必要があると思います。これは、fluent-nhibernateがEmployeeToJobTitleMatchLinkテーブルにFKを作成するために表記法を使用しているためです。 HasMayマッピングの一部としてKeyColumnを使用すると、規約が上書きされます。

次のようなもの: -

public class JobTitleMap : ClassMap 
{ 
    public JobTitleMap() 
    { 
        Id(x => x.JobTitleUUID).GeneratedBy.GuidComb(); 

        OptimisticLock.Version(); 
        Version(x => x.TheVersionProperty) 
            .Column("MyVersionColumn") 
            .Not.Nullable() 
            .CustomSqlType("timestamp") 
            .Generated.Always(); 

        Map(x => x.JobTitleName); 
        Map(x => x.CreateDate); 
        HasMany(x => x.MyJobTitleToEmployeeMatchLinks) 
            .Inverse() 
            .Cascade.All()
            **.KeyColumn("TheJobTitleUUID")**
    } 
} 
1
追加された
ありがとう(プラスワン)。私はEmployeeToJobTitleMatchLinkMapクラスから頭を出すことができませんでした。 :<�あなたのヒントは機能します。 (EmployeeMap.cs内)HasMany(x => x.MyEmployeeToJobTitleMatchLinks).Inverse().Cascade.All().KeyColumn( "TheEmployeeUUID"); (JobTitleMap.cs内)HasMany(x => x.MyJobTitleToEmployeeMatchLinks).Inverse().Cascade.All().KeyColumn( "TheJobTitleUUID")
追加された 著者 granadaCoder,