0

データをデータベースに戻すクライアント側アプリを開発しています。クライアントには、タイプ 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 の関係で定義しているためです。

ここでのオプションは何ですか? 私はかなり困惑しています。

4

1 に答える 1