2

そのうちの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を指定すると、好きな列を指定できるようになるはずです。それは本当に可能ですか?私は読み間違えていますか?

4

1 に答える 1

1

ParentKeyColumnとChildKeyColumnは、結合されたエンティティテーブルの列ではなく、リンクテーブルの列名を指定します。必要なのはPropertyRefChildPropertyRef結合するプロパティを指定するためのhasmanytomanyです。

于 2012-08-19T20:25:39.693 に答える