일반적으로 nHibernate를 사용하여 내 엔티티의 고유 ID를 생성하지만 코드로 생성하려고합니다. 다음 예를 고려해보십시오. (내가 잘못한 일을하는 경우 DDD를 처음 사용하는 경우이를 지적하십시오.)새로운 GUID를 사용하여 자식 엔티티를 생성하는 집계 루트
이들은 모두 동일한 어셈블리, 즉 도메인 모델에 속하는 클래스입니다.
public interface AggregateRootState
{
bool CanAddChild();
bool CanModifyChild();
bool CanDeleteChild();
}
public class AggregateRoot
{
private AggregateRootState aggregateRootState;
public IList<ChildEntity> ChildEntityList {get; internal set;}
public bool CanAddChild()
{
return aggregateRootState.CanAddChild();
}
public void AddChild(ChildEntityParameters childEntityParameters)
{
if (!CanAddChild())
throw new NotImplementedException("aggregate root not in correct state.");
ChildFactory.CreateChildEntity(childEntityParameters);
}
public bool CanModifyChild()
{
return aggregateRootState.CanModifyChild();
}
public void ModifyChild(ChildEntityParameters childEntityParameters)
{
if (!CanModifyChild())
throw new NotImplementedException("aggregate root not in correct state.");
ChildEntity childEntity = ChildEntityList.First(c => c.Id == childEntityParameters.Id);
childEntity.Property1 = childEntityParameters.Property1;
childEntity.Property2 = childEntityParameters.Property2;
}
public bool CanDeleteChild()
{
return aggregateRootState.CanDeleteChild();
}
public void DeleteChild(Guid Id)
{
if (!CanDeleteChild())
throw new NotImplementedException("aggregate root not in correct state");
ChildEntityList.Remove(ChildEntityList.First(c => c.Id == Id));
}
public void Validate()
{
//code to validate the object and ensure it is in a savable state.
}
}
public class ChildEntityParameters
{
public Guid Id {get; set;}
public string Property1 {get; set;}
public string Property2 {get; set;}
}
public class ChildEntity
{
internal ChildEntity() { }
public Guid Id {get; set;}
public string Property1 {get; internal set;}
public string Property2 {get; internal set;}
}
internal static class ChildFactory
{
public static void CreateChildEntity(ChildEntityParameters childEntityParameters)
{
ChildEntity childEntity = new ChildEntity();
childEntity.Property1 = childEntityParameters.Property1;
childEntity.Property2 = childEntityParameters.Property2;
}
}
내 서비스 레이어는 다음과 같이 보일 것입니다 :
//for simplicity I have arguments rather than using the request/response pattern.
public class ServiceLayer
{
public void AddChildEntity(Guid aggregateRootId, string string1, string string2)
{
AggregateRoot aggregateRoot = aggregateRootRepository.FindBy(aggregateRootId);
ChildEntityParameters childEntityParameters = new ChildEntityParameters();
childEntityParameters.Property1 = string1;
childEntityParameters.Property2 = string2;
aggregateRoot.AddChild(childEntityParameters);
aggregateRoot.Validate(); //will throw exception if there is something wrong.
aggregateRootRepository.Save(aggregateRoot);
}
}
지금이 모든 것이 잘 좋은 작동합니다. 그러나 새로 생성 된 ChildEntity의 ID를 프리젠 테이션 레이어로 반환하려면 어떻게해야할까요? 현재로서는 불가능합니다. 전체 객체 그래프를 반환해야합니다. 내가 생각할 수있는 유일한 대안은 내 코드를 다음과 같이 변경하는 것입니다.
internal static class ChildFactory
{
public static void CreateChildEntity(ChildEntityParameters childEntityParameters)
{
ChildEntity childEntity = new ChildEntity();
**childEntity.Id = Guid.NewGuid();**
childEntity.Property1 = childEntityParameters.Property1;
childEntity.Property2 = childEntityParameters.Property2;
}
}
public class ServiceLayer
{
public **Guid** AddChildEntity(Guid aggregateRootId, string string1, string string2)
{
**Guid Id;**
AggregateRoot aggregateRoot = aggregateRootRepository.FindBy(aggregateRootId);
ChildEntityParameters childEntityParameters = new ChildEntityParameters();
childEntityParameters.Property1 = string1;
childEntityParameters.Property2 = string2;
**Id = aggregateRoot.AddChild(childEntityParameters);**
aggregateRoot.Validate(); //will throw exception if there is something wrong.
aggregateRootRepository.Save(aggregateRoot);
return Id;
}
}
이것이 잘못된 것입니까? 아니면 완벽하게 괜찮습니까? 누군가가 명확히 할 수 있다면 좋을 것입니다!
나는 꽤 공정한 비트를 참조 할 것 같은 그 책을 조사해야합니다. 그래서 내 개체에 대해 개체를 만들 때 ID를 생성해야한다고 제안하는 중입니까? 집계 루트를 포함하여? 원본 질문을 게시 한 후 추가 조사를 수행하여 ID를 지정하면 nHibernate가 레코드를 삽입하거나 업데이트할지 여부를 알 수 없음을 발견했습니다. 이것은 nhibernate의 구성을 변경하는 문제일까요? –
NH가'Save()'를 통해 당신에게 ID를 생성하도록 요청할 수 있습니까? 또는 id = assigned가되도록 매핑을 변경 하시겠습니까? –
나는 혼란 스럽다. NH가 저에게 Save()를 통해 ID를 생성하게되면 새로 생성 된 하위 엔티티의 ID를 가져올 수 없다는 원래 문제로 돌아갑니다. 그래서 나는 id = assigned가되도록 매핑을 변경해야한다고 생각합니다. 이 문제는 여기에 언급 된 바와 같이 있습니다 : http://stackoverflow.com/questions/5048728/fluent-nhibernate-generated-and-assigned-id-columns 그러나 나는 대안을 정말로 보지 못합니까? 나쁜 디자인 결정 : http://www.nhforge.org/doc/nh/en/index.html#mapping-declaration-id-assigned –