そのうちの2つで非PK列を使用していくつかのテーブルを関連付ける必要があります。テーブルとFKは次のように設定されます。
したがって、メッセージは、MessageUserGroupsテーブルを介して多くのユーザーとグループに割り当てることができます。さらに、UserGroupsテーブルを介してユーザーを多くのグループに割り当てることができます。
ユーザーとグループのAdGuidフィールド(uniqueidentifier)は、従来の理由から主キーではありません。ただし、MessageUserGroupsのUserIdフィールドとGroupIdフィールドを使用して、AdGuidフィールドを介してメッセージをユーザーとグループに関連付けたいと思います。
さらに、Message.AuthorIdをUser.AdGuidに関連付けるUserにPostedMessagesプロパティを設定し、MessageUserGroupsを介してメッセージに関連付けられるUserとGroupにMessagesプロパティを設定したいと思います。
これをFluentNHibernateに説明するにはどうすればよいですか?
現在、マッピングは次のようになっています。
public MessageMap()
{
Id(m => m.Id);
References(m => m.Author).Nullable().ForeignKey("FK_Messages_Author").Column("AuthorId").Fetch.Join().PropertyRef(u => u.AdGuid);
HasManyToMany<users.user>(m => m.Users)
.Cascade.All()
.ParentKeyColumn("MessageId")
.ChildKeyColumn("UserId")
.Table("MessageUserGroups")
.FetchType.Join();
HasManyToMany<users.group>(m => m.Groups)
.Cascade.All()
.ParentKeyColumn("MessageId")
.ChildKeyColumn("GroupId")
.Table("MessageUserGroups")
.FetchType.Join();
}
public UserMap()
{
Id(u => u.Id);
Map(u => u.AdGuid);
HasManyToMany<staff.Message>(u => u.Messages)
.Cascade.All()
.ParentKeyColumn("AdGuid")
.ChildKeyColumn("UserId")
.Inverse()
.LazyLoad()
.Table("MessageUserGroup")
HasMany<staff.Message>(u => u.PostedMessages)
.Cascade.All()
.KeyColumn("AuthorId")
.Inverse()
.LazyLoad()
.Table("Messages")
HasManyToMany<Group>(u => u.Groups)
.Cascade.All()
.Not.LazyLoad()
.Cascade.All()
.ParentKeyColumn("UserID")
.ChildKeyColumn("GroupID")
.Table("UserGroups")
}
public GroupMap()
{
Id(g => g.Id);
Map(g => g.AdGuid);
HasManyToMany<staff.Message>(g => g.Messages)
.Cascade.All()
.ParentKeyColumn("AdGuid")
.ChildKeyColumn("GroupId")
.Inverse()
.LazyLoad()
.Table("MessageUserGroup")
HasManyToMany<User>(g => g.Users)
.Inverse()
.Cascade.All()
.ParentKeyColumn("GroupId")
.ChildKeyColumn("UserId")
.Table("UserGroups")
}
少し長いです、私は知っています。NHを使用してメッセージを正常に照会できます。ただし、ユーザーまたはグループのメッセージプロパティを遅延読み込みすると、NHは次のSQLを生成します(簡潔にするために余分なプロパティは削除されています)。
SELECT users0_.MessageId as MessageId1_, users0_.UserId as UserId1_, user1_.Id
as id38_0_, user1_.AdGuid as guid38_0_ FROM MessageUserGroups users0_
LEFT OUTER JOIN Users user1_ on users0_.UserId=user1_.Id WHERE users0_.MessageId=@p0
この結合は、uniqueidentiferMessageUserGroups.UserIdをbigintUser.Idと比較しようとしているため、無効です。
同様に、User.PostedMessagesを遅延ロードすると、このSQLが生成されます(ここでも省略されます)。
SELECT postedmess0_.AuthorId as AuthorId1_, postedmess0_.Id as Id1_, postedmess0_.Id as Id43_0_, postedmess0_.AuthorId as AuthorId43_0_
FROM Staff.Messages postedmess0_
WHERE postedmess0_.AuthorId=@p0
また@p0
、89に設定されています。これは、テストしているユーザーのIDですが、AuthorIdはuniqueidentifierである必要があります。
それらの両方の後、私は:を取得しSqlException
ます。Operand type clash: uniqueidentifier is incompatible with bigint
これは予想されることです。
(流暢な)NHibernateは常にPKに参加したいと考えているようですが、ドキュメントでは、ParentKeyColumnとChildKeyColumnを指定すると、好きな列を指定できるようになるはずです。それは本当に可能ですか?私は読み間違えていますか?