문제

DDD, 저장소 패턴 및 ORM에 관한 다소 우스운 질문이 있습니다. 이 예에는 3 개의 수업이 있습니다. 주소, 회사 그리고 사람. 사람은 회사의 구성원이며 주소가 있습니다. 회사에는 주소도 있습니다.

이 클래스는 데이터베이스 모델을 반영합니다. 내 모델의 종속성을 제거 했으므로 nhibernate 또는 linqtosql과 같은 특정 ORM 라이브러리에 묶여 있지 않습니다. 이러한 종속성은 저장소 내부에서 처리됩니다.

내부 저장소 ~이있다 SavePerson (사람) 방법 삽입/업데이트 데이터베이스에 이미 존재하는지 여부에 따라 사람.

Person Object에는 회사가 있으므로 현재 저장 한 전화를 할 때 회사 부동산의 가치도 저장/업데이트합니다. 이 절차 중에 회사의 모든 데이터 (이름 및 주소)를 삽입 / 업데이트합니다.

그러나 저는 회사의 데이터가 사람을 다루는 동안 변화 할 수있는 사례를 생각하기가 어려운 시간을 가지고 있습니다. 회사를 사람에게 할당하거나 다른 회사로 사람을 옮길 수 있기를 원합니다. 나는 새로운 사람과 함께 새로운 회사를 만들고 싶지 않다고 생각합니다. 따라서 SaveCompany 호출은 불필요한 데이터베이스 호출을 도입합니다. 사람을 저장할 때는 CompanyID 열을 업데이트 할 수 있어야합니다.

그러나 Person Class에는 회사 자산이 있기 때문에 업데이트 / 삽입하려는 경향이 있습니다. 엄격한/순수한 관점에서 SavePerson 방법은 전체 사람을 구해야합니다.

선호하는 방법은 무엇입니까? 사람을 저장하거나 모든 데이터를 저장할 때 회사 부동산의 회사를 삽입/업데이트합니까? 또는 두 시나리오 모두에 대해 두 가지 다른 방법을 만들 수 있습니까 (무엇을 이름을 지을 것인가?)

또한 또 다른 질문, 저는 현재 사람, 주소 및 회사를 구하는 뚜렷한 방법을 가지고 있으므로 회사를 구할 때도 SaveadDress에게도 전화합니다. linqToSQL을 사용한다고 가정 해 봅시다. 이것은 회사와 주소를 동일한 LINQ 쿼리에 삽입/업데이트하지 않음을 의미합니다. 2 개의 선택 전화가있을 것 같습니다 (회사가 존재하는지 확인하고 주소가 존재하는지 확인). 그런 다음 두 가지 삽입/업데이트가 두 가지를 호출합니다. 더 많은 복합 모델 클래스가 도입되면 더욱 LINQTOSQL이 이러한 호출을 최적화 할 수있는 방법이 있습니까?

public class Address
{
    public int AddressId { get; set; }
    public string AddressLine1 { get; set; }
    public string AddressLine2 { get; set; }
    public string City { get; set; }
    public string PostalCode { get; set; }        
}

public class Company
{
    public int CompanyId { get; set; }
    public string Name { get; set; }
    public Address Address { get; set; }
}


public class Person
{
    public int PersonId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public Company Company { get; set; }
    public Address Address { get; set; }

}

편집하다

또한 참조하십시오 이 후속 질문. 값 객체는 데이터베이스에 어떻게 저장됩니까?

도움이 되었습니까?

해결책

나는 최근에 Keith가 제안한 Irepository 접근법을 사용했습니다. 그러나 여기서 그 패턴에 집중해서는 안됩니다. 대신, DDD 플레이 북에는 여기에 적용 할 수있는 몇 가지 조각이 더 있습니다.

사용 가치 객체 주소를 위해

먼저, 여기에 적용 할 수있는 값 객체 (VO)의 개념이 있습니다. 당신의 경우, 그것은 주소가 될 것입니다. 값 객체와 엔티티 객체의 차이점은 엔티티가 신원이 있다는 것입니다. Vos는 그렇지 않습니다. VO의 정체성은 실제로 고유 한 정체성이 아니라 속성의 합입니다. 책에서 도메인 드라이브 디자인을 신속하게 (이것은 또한 무료 PDF 다운로드이기도합니다), 그는 주소가 실제로 지구의 요점 일 뿐이며 사람과 같은 별도의 사회 보안과 같은 정체성이 필요하지 않다고 말함으로써 이것을 잘 설명합니다. 지구의 그 지점은 거리, 수, 도시, 지퍼 및 국가의 조합입니다. 위도와 경도 값을 가질 수는 있지만 여전히 두 지점의 조합이기 때문에 정의상 VOS입니다.

사용 서비스 당신의 엔티티를 단일 엔터티로 결합 할 수 있습니다.

또한 DDD 플레이 북의 서비스 개념을 잊지 마십시오. 예를 들어, 해당 서비스는 다음과 같습니다.

public class PersonCompanyService
{
  void SavePersonCompany(IPersonCompany personCompany)
  {
    personRepository.SavePerson();
    // do some work for a new company, etc.
    companyRepository.SaveCompany();
  }
}

다른 작업의 조합을 조정하기 위해 유사한 조치가 필요한 두 개체가 필요한 두 엔티티가있을 때 서비스가 필요합니다. 귀하의 경우, 사람 ()을 저장하고 동시에 빈 회사 ()를 만듭니다.

Orms worsualyl은 신원, 기간이 필요합니다.

이제 데이터베이스에서 주소 VO를 저장하는 방법은 무엇입니까? 당신은 분명히 iaddressrepository를 사용합니다. 그러나 대부분의 ORM (예 : LingtoSQL)에는 모든 객체에 정체성이 필요하기 때문에 다음은 트릭이 있습니다. 모델의 내부로 아이덴티티를 표시하므로 모델 레이어 외부에서 노출되지 않습니다. 이것은 Steven Sanderson 자신의 조언입니다.

public class Address
{
  // make your identity internal
  [Column(IsPrimaryKey = true
    , IsDbGenerated = true
    , AutoSync = AutoSync.OnInsert)]
  internal int AddressID { get; set; }

  // everything else public
  [Column]
  public string StreetNumber { get; set; }
  [Column]
  public string Street { get; set; }
  [Column]
  public string City { get; set; }
  ...
}

다른 팁

최근 저장소 패턴을 사용한 경험을 통해 일반적인 저장소 인 T의 일반적인 저장소를 사용하면 혜택을 볼 수 있다고 생각합니다. 그렇게하면 SavePerson (Person)과 같은 저장소 메소드를 추가 할 필요가 없습니다. 대신 : 당신은 다음과 같은 것을 가질 것입니다.

IRepository<Person> personRepository = new Repository<Person>();
Person realPerson = new Person();
personRepository.SaveOrUpdate(realPerson);

이 방법은 또한 구동 개발 및 조롱을 테스트하는 데 적합합니다.

설명에서 행동에 대한 질문은 도메인에 대한 관심이 될 것이라고 생각합니다.

public Company Company { get; private set; }

내 요점은; 데이터가 데이터베이스에 지속되는 방법에 대해 걱정하지 않고 도메인을 모델링하십시오. 이것은 도메인 모델을 사용할 서비스에 대한 관심사입니다.

저장소로 돌아가서 이것을 살펴보십시오. 게시하다 LinqToSQL에 대한 Irepository에 대한 좋은 설명. Mike의 블로그에는 저장소에 대한 다른 많은 게시물이 있습니다. 당신이 ORM을 선택하게되면 LinqToSQL보다 hhibernate를 추천 할 수 있습니다. 후자는 이제 소멸되고 Nhibernate에는 훌륭한 지원 커뮤니티가 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top