データをデータベースに戻すクライアント側アプリを開発しています。クライアントには、タイプ PlaylistItem のオブジェクトを作成する機能があります。PlaylistItem を作成するときに、生成された ID でデータベースが応答するのを待ちません。代わりに、クライアントに ID を生成させますが、{ PlaylistID, PlaylistItemID } の PK を使用して PlaylistItem をデータベースに書き込みます。PlaylistID はサーバーによって生成されます。Jon Skeetと少し話し合った後、私はこのアプローチに従いました
今、私は NHibernate で物事を動かそうとしていますが、かなり大きな問題に直面しています。私が読んだすべてのリソースは、「NHibernate は複合キーの使用を強く思いとどまらせます。レガシー DB で作業している場合にのみ使用してください。」と述べています。私はレガシー DB に取り組んでいないので、変更を加える必要があると思います。ただし、そのようなシナリオで私の代替手段が何であるかはわかりません。
PlaylistItem の NHibernate マッピングと対応するクラスは次のとおりです。
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Streamus" namespace="Streamus.Backend.Domain">
<class name="PlaylistItem" table="[PlaylistItems]" lazy="false" >
<composite-id>
<key-property name="Id" />
<key-property name="PlaylistId"/>
</composite-id>
<property name="Title" not-null="true" />
<many-to-one name="Playlist" column="PlaylistId"/>
</class>
</hibernate-mapping>
[DataContract]
public class PlaylistItem
{
[DataMember(Name = "playlistId")]
public Guid PlaylistId
{
get { return Playlist.Id; }
set { Playlist.Id = value; }
}
public Playlist Playlist { get; set; }
[DataMember(Name = "id")]
public Guid Id { get; set; }
// Store Title on PlaylistItem as well as on Video because user might want to rename PlaylistItem.
[DataMember(Name = "title")]
public string Title { get; set; }
public PlaylistItem()
{
// Id shall be generated by the client. This is OK because it is composite key with
// PlaylistId which is generated by the server.
Id = Guid.Empty;
Title = string.Empty;
}
private int? _oldHashCode;
public override int GetHashCode()
{
// Once we have a hash code we'll never change it
if (_oldHashCode.HasValue)
return _oldHashCode.Value;
bool thisIsTransient = Equals(Id, Guid.Empty);
// When this instance is transient, we use the base GetHashCode()
// and remember it, so an instance can NEVER change its hash code.
if (thisIsTransient)
{
_oldHashCode = base.GetHashCode();
return _oldHashCode.Value;
}
return Id.GetHashCode();
}
public override bool Equals(object obj)
{
PlaylistItem other = obj as PlaylistItem;
if (other == null)
return false;
// handle the case of comparing two NEW objects
bool otherIsTransient = Equals(other.Id, Guid.Empty);
bool thisIsTransient = Equals(Id, Guid.Empty);
if (otherIsTransient && thisIsTransient)
return ReferenceEquals(other, this);
return other.Id.Equals(Id);
}
}
NHibernate は、「この SqlParameterCollection のカウント = n のインデックス n が無効です」というエラー メッセージとともに例外をスローします。hbm.xml ファイルに重複した宣言がある場合に発生すると理解しています。私の理解では、これは、PlaylistId をキー プロパティとして、また多対 1 の関係で定義しているためです。
ここでのオプションは何ですか? 私はかなり困惑しています。