私はこの質問について「全体」のインターネットを検索しましたが、かなり複雑であるため、検索するのは非常に困難です。「Fluent NHibernate Many to Many with a bridge table with extra columns」などで検索してみてください...
さて、説明を簡単にするために、参照できるいくつかのテーブルを定義しません。表: ユーザー、表: 関数、表: User_Has_Function。
1 人のユーザーは多くの関数を持つことができ、関数は多くのユーザーを持つことができます。これはブリッジ テーブル User_Has_Function にリンクされています。ブリッジ テーブルには、関係にのみ関連する追加の列があります。
とにかく、FNH にはこれに対する自動解決策がないことがわかりました。基本的には、User から User_Has_Function への 1 対多の関係と、User_Has_Function から Function への多対 1 の関係を使用する必要があるため、"[One] to [Many - Many] [One] へ」。
私はこのリンクhttp://sessionfactory.blogspot.com/2010/12/many-to-many-relationships-with.htmlのように、明らかにxmlの代わりにFNHクラスマッピングを使用して解決しました。
しかし、私は解決策に満足していません。この機能を適切に行うために、このすべての作業を手動で行う必要がありますか? また、現在のように、ブリッジ テーブルに重複を挿入します。
私の頭の中で私は何か間違ったことをしています。これに対するサポートがないとは想像できません。SaveAndUpdate() を使用するだけで、重複は挿入されず、エンティティを削除すると関係も削除され、関係が残っていない場合はエンティティ自体が削除されます。
さて、ここに私のエンティティとマッピングがあります。私は Fluent NHibernate に非常に慣れていないので、何か非常に間違ったことをしたとしても大声で叫ばないでください。:)
エンティティ:
public class XUser
{
public virtual int Id { get; set; }
...
public virtual IList<XUserHasXFunction> XUserHasXFunctions { get; set; }
public XUser()
{
XUserHasXFunctions = new List<XUserHasXFunction>();
}
public virtual void AddXFunction(XFunction xFunction, int isActive)
{
var xUserHasXFunction = new XUserHasXFunction()
{
XUser = this,
XFunction = xFunction,
DeployedDate = DateTime.Now
};
XUserHasXFunctions.Add(xUserHasXFunction);
xFunction.XUserHasXFunctions.Add(xUserHasXFunction);
}
public virtual void RemoveXFunction(XFunction xFunction)
{
var xUserHasXFunction = XUserHasXFunctions.Single(x => x.XFunction == xFunction);
XUserHasXFunctions.Remove(xUserHasXFunction);
xFunction.XUserHasXFunctions.Remove(xUserHasXFunction);
}
}
public class XFunction
{
public virtual int Id { get; set; }
...
public virtual IList<XUserHasXFunction> XUserHasXFunctions { get; set; }
public XFunction()
{
XUserHasXFunctions = new List<XUserHasXFunction>();
}
public virtual void AddXUser(XUser xUser, int isActive)
{
var xUserHasXFunction = new XUserHasXFunction()
{
XUser = xUser,
XFunction = this,
DeployedDate = DateTime.Now
};
XUserHasXFunctions.Add(xUserHasXFunction);
xUser.XUserHasXFunctions.Add(xUserHasXFunction);
}
public virtual void RemoveXUser(XUser xUser)
{
var xUserHasXFunction = XUserHasXFunctions.Single(x => x.XUser == xUser);
XUserHasXFunctions.Remove(xUserHasXFunction);
xUser.XUserHasXFunctions.Remove(xUserHasXFunction);
}
}
public class XUserHasXFunction
{
public virtual int Id { get; set; }
public virtual XUser XUser { get; set; }
public virtual XFunction XFunction { get; set; }
public virtual DateTime DeployedDate { get; set; }
}
マッピング:
public class XUserMap : ClassMap<XUser>
{
public XUserMap()
{
Id(x => x.Id, "ID").GeneratedBy.Sequence("SEQ").Column("ID");
Table("XUSER");
...
HasMany(x => x.XUserHasXFunctions).Cascade.All();
}
}
public class XFunctionMap : ClassMap<XFunction>
{
public XFunctionMap()
{
Id(x => x.Id, "ID").GeneratedBy.Sequence("SEQ").Column("ID");
Table("XFUNCTION");
...
HasMany(x => x.XUserHasXFunctions).Cascade.All();
}
}
public class XUserHasXFunctionMap : ClassMap<XUserHasXFunction>
{
public XUserHasXFunctionMap()
{
Id(x => x.Id, "ID").GeneratedBy.Sequence("SEQ").Column("ID");
Table("USER_HAS_FUNCTION");
Map(x => x.DeployedDate, "DEPLOYED_DATE");
References(x => x.XUser).ForeignKey("XUSER_ID").Cascade.SaveUpdate();
References(x => x.XFunction).ForeignKey("XFUNCTION_ID").Cascade.SaveUpdate();
}
}