그렇다면 Entity Framework가 레이어간에 데이터를 전송하기 위해 동일한 속성을 가진 새 객체를 생성하는 로직을 제공하지 않는 이유가 궁금합니다.
엔티티 프레임 워크로 생성 한 엔티티 오브젝트를 사용합니다.
그렇다면 Entity Framework가 레이어간에 데이터를 전송하기 위해 동일한 속성을 가진 새 객체를 생성하는 로직을 제공하지 않는 이유가 궁금합니다.
엔티티 프레임 워크로 생성 한 엔티티 오브젝트를 사용합니다.
답변:
너하기에 달렸다.
대부분의 사람들은 그것이 좋은 습관은 아니지만 어떤 경우에는 그것을 벗어날 수 있다고 말할 것입니다.
EF는 여러 가지 이유로 DDD와 잘 어울리지 않았지만 두 가지가 있습니다. 엔터티에 매개 변수화 된 생성자를 가질 수 없으며 컬렉션을 캡슐화 할 수 없습니다. 도메인 모델에는 데이터와 동작이 모두 포함되어야하므로 DDD는이를 사용합니다.
어떤 식 으로든 EF는 빈혈 도메인 모델을 갖도록 강요하며이 경우 엔터티를 DTO로 사용할 수 있습니다. 탐색 속성을 사용하는 경우 일부 문제가 발생할 수 있지만 해당 엔티티를 직렬화하여 유선으로 전송할 수 있습니다. 실용적이지 않을 수 있습니다. 전송할 필요가없는 속성이있는 각 엔티티의 직렬화를 제어해야합니다. 더 쉬운 방법은 데이터 전송에 맞게 개별 클래스를 간단하게 디자인하는 것입니다. 이를 위해 AutoMapper 와 같은 라이브러리 가 생성됩니다.
예를 들어 Person
, 다음과 같이 정의 된 클래스가 있다고 가정하십시오 .
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; get; }
// plus a bunch of other properties relevant about a person
}
어딘가에 직원 목록을 표시하려는 경우 Id
, FirstName
및 을 전송하는 것이 실용적 일 수 있습니다 LastName
. 그러나 다른 모든 관련성이없는 속성을 보내야합니다. 응답의 크기에 신경 쓰지 않는다면 큰 문제는 아니지만 일반적인 아이디어는 관련 데이터 만 보내는 것입니다. 반면에 개인 목록을 반환하는 API를 디자인하면이 경우 모든 속성을 보내야 할 수 있으므로 엔터티를 serialize하고 보내는 것이 좋습니다. 이 경우 DTO 클래스 작성은 논쟁의 여지가 있습니다. 엔터티와 DTO를 혼합하는 것을 좋아하는 사람들도 있고 그렇지 않은 사람들도 있습니다.
업데이트 된 질문에 대답하기 위해 EF는 ORM입니다. 데이터베이스 레코드를 객체에 매핑하거나 그 반대로 매핑하는 것이 그 역할입니다. EF를 통과하기 전후에 이러한 객체로 수행하는 작업은 그 문제의 일부가 아닙니다. 해서는 안됩니다.
전혀 그렇지 않다.
이상적으로 DTO는 지속성 저장소 (일명 데이터베이스 테이블)와 일치합니다.
그러나 비즈니스 클래스가 반드시 일치하는 것은 아닙니다. 추가 클래스가 필요하거나 데이터베이스에있는 클래스와 분리되거나 결합 된 클래스가 필요할 수 있습니다. 응용 프로그램이 작 으면 실제로 이런 종류의 문제는 보이지 않지만 중대형 응용 프로그램에서는 자주 발생합니다.
또 다른 것은 DTO가 지속성을 다루는 모든 영역의 일부이며 비즈니스 계층은 그에 대해 아무것도 알지 못한다는 것입니다.
실제로는 매우 나쁜 생각입니다. Martin Fowler는 로컬 DTO에 관한 기사를 가지고 있습니다.
간단히 말해, DTO
패턴은 프로세스 외부로 데이터를 전송하는 데 사용되었습니다 (예 : 동일한 프로세스 내의 레이어 간이 아니라 와이어를 통해).
아니요, 나쁜 습관입니다.
몇 가지 이유 :
@JsonIgnore
Java 세계 와 같은 일부 주석을 사용하여 필드를 무시할 수는 있지만 다음 문제가 발생합니다 ...get
엔터티 의 메서드 를 호출하기 만하면됩니다 .따라서 엔터티 필드를 Dto에 매핑하여이 작업을 도와주는 일종의 매퍼 도구를 더 쉽고 안전하게 사용할 수 있습니다.
@Dherik이 말한 것을 완성하기 위해 엔티티 객체를 데이터 전송 객체로 사용하는 주요 문제는 다음과 같습니다.
트랜잭션에서 DTO로 사용하기 때문에 엔터티에 대한 변경 사항을 커밋 할 위험이 있습니다 (트랜잭션에서 세션 엔터티를 분리 할 수있는 경우에도 대부분의 경우 이전에이 상태를 확인해야 함) 엔터티 -DTO에 대한 수정 사항 및 거래에 있지 않거나 수정 사항을 유지하지 않으려면 세션이 닫혔는지 확인하십시오).
클라이언트와 서버간에 공유하는 데이터의 크기 : 때로는 요청 응답의 크기를 최소화하기 위해 엔티티의 모든 내용을 클라이언트에 보내지 않으려는 경우가 있습니다. 엔터티에서 DTO를 분리하면 특정 사용 사례로 보내려는 데이터를 특수화 할 수 있습니다.
가시성 및 유지 관리 : 엔티티 필드에서 jpa / hibernate 주석을 관리하고 잭슨 주석을 유지하여 동일한 위치에서 json으로 직렬화해야합니다 (엔티티 구현과 분리하여 엔티티 인터페이스에서 분리 할 수 있더라도) 실재). 그런 다음 새 필드를 추가 할 때 DTO 컨텐츠를 변경하는 경우 다른 사람이 해당 필드가 엔티티 필드이므로 데이터베이스와 관련된 테이블 필드라고 생각할 수 있습니다 ( @Transient
모든 DTO 필드에 주석을 사용할 수있는 경우에도) 경우에 ..!).
내 의견으로는 엔터티를 읽을 때 소음이 발생하지만 내 의견은 분명히 주관적입니다.