我正在开发一个将数据传回数据库的客户端应用程序。客户端可以创建 PlaylistItem 类型的对象。在创建 PlaylistItem 时,我不会等待数据库以生成的 ID 进行响应。相反,我让客户端生成 ID,但将 PlaylistItem 写入数据库,PK 为 { PlaylistID, PlaylistItemID }。PlaylistID 由服务器生成。在与 Jon Skeet 讨论了一下之后,我采用了这种方法
现在,我正试图让 NHibernate 中的事情发生变化,但我遇到了一些非常严重的问题。我读到的所有资源都在说,“NHibernate 强烈反对使用复合键。只有在你使用遗留数据库时才使用它们。” 我不是在处理遗留数据库,所以我认为我应该做出改变。但是,我不知道在这种情况下我的替代方案是什么。
这是 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 抛出异常并显示错误消息“Invalid index n for this SqlParameterCollection with Count=n”。我知道当 hbm.xml 文件中有重复声明时会出现这种情况。据我了解,这是因为我将 PlaylistId 定义为键属性,并且再次以多对一关系定义。
我在这里有什么选择?我很困惑。