데이터를 다시 데이터베이스로 전달하는 클라이언트 측 응용 프로그램을 개발 중입니다. 클라이언트는 PlaylistItem 유형의 객체를 생성 할 수 있습니다. PlaylistItem을 만들 때 데이터베이스가 생성 된 ID로 응답하는 것을 기다리지 않습니다. 대신, 나는 클라이언트가 ID를 생성하게하지만 {PlaylistID, PlaylistItemID}의 PK로 데이터베이스에 PlaylistItem을 작성합니다. PlaylistID는 서버에 의해 생성됩니다. I followed this approach after talking things over a bit with Jon Skeet클라이언트 생성 ID 인 PK는 상위 키가있는 복합 키입니다. NHibernate는 행복하지 않다. 대안?
이제, 나는 NHibernate에서 일하는 것을 얻으려고 노력하고 있지만 꽤 심각한 문제가 있습니다. 내가 읽은 모든 자료는 "NHibernate는 합성 키의 사용에 대해 크게 반대합니다. 레거시 DB에서 작업 할 때만 사용하십시오." 난 레거시 DB에서 일하고 있지 않다. 그래서 나는 변화를해야한다고 생각한다. 그러나, 나는 그러한 대안에서 나의 대안이 무엇인지 모릅니다.
여기 PlaylistItem의 NHibernate에 매핑 및 해당 클래스의 ". = N 백작이 SqlParameterCollection에 대한 잘못된 인덱스 N"<?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에 오류 메시지와 함께 예외가 발생합니다 hbm.xml 파일에 중복 된 선언이있을 때 발생하는 것으로 알고 있습니다. 필자는 PlaylistId를 키 속성으로 정의하고 다시 다 대일 관계로 정의하므로이 점이 이해할 수 있습니다.
내 옵션에는 어떤 것들이 있습니까? 나는 꽤 난처한 처지이다.
서버가 성공적으로 삽입 될 때까지 기다리는 것을 원하십니까? 클라이언트는 서버를 기다리지 않고 작업 할 수 있어야하지만 클라이언트 측에서 생성 한 ID 만 신뢰해서는 안된다는 것도 이해합니다. 나는 서버가 클라이언트가 사용할 수있는 유효한 ID들을 묶어서 보내고 서버가 사용 된 키가 유효하다는 것을 확인하도록 고려하고 있지만 NHibernate는 저장이 Create 또는 Update인지를 알 수 없다. ID는 항상 설정 될 것입니다 ... –
나는 그 문제를 해결할 것 같지 않습니다. "GetPlaylistItemByClientID"라고 말하면 클라이언트가 PK인지 또는 값을 고유하게 식별하는 데 사용되는 다른 열에 관계없이 UUID를 생성하는 클라이언트 인 경우 "GetPlaylistItemByPKID"를 말한 것과 동일한 문제입니다. 데이터베이스에서 클라이언트 측에서 생성 한 값의 고유성에 의존 할 수는 없습니다. 맞습니까? –
클라이언트 ID가 고유한지 확인하기 위해 서버에 AJAX 요청을 발행하면 클라이언트가 응답하기 전에 서버의 확인을 기다려야합니다. 이것은 서버가 ID를 생성 할 때까지 기다리는 것과 같습니다. 어쩌면 데이터베이스 저장을 기다릴 필요가 없기 때문에 더 빨라질 수도 있지만 모든 대기 시간은 서버가주고받는 메시지가 아닌 서버로 /부터 전달되는 메시지에서 비롯됩니다. –