2012-11-09 4 views
4

내가 할 수있는 다음과 같은 C# 클래스가 있다고 가정 해 봅시다. 매개 변수화 된 생성자를 사용하여 설정할 수 있습니다.POCO의, ORM 및 불변성. 함께 일하는 방법?

public class InsulineInjection 
{ 
    private InsulineInjection() 
    { 
     // We don't want to enable a default constructor. 
    } 

    public InsulineInjection(Millilitre millilitre, DateTime dateTime, string remark) 
    { 
     this.Remark = remark; 
     this.DateTime = dateTime; 
     this.Millilitre = millilitre; 
    } 

    public string Remark { get; private set; } 
    public DateTime DateTime { get; private set; } 
    public Millilitre Millilitre { get; private set; } 
} 

이제 ORM을 사용하여이 POCO를 만들고 싶습니다. 그러나 내가 볼 수있는 한 모든 .NET ORM의 속성에 액세스 할 수 있어야하며이 POCO를 만들 수있는 공용 생성자가 있어야합니다. 그래서 내 POCO를 다음과 같이 변경해야합니다.

public class InsulineInjection 
{ 
    public InsulineInjection() 
    { 
    } 

    public InsulineInjection(Millilitre millilitre, DateTime dateTime, string remark) 
    { 
     this.Remark = remark; 
     this.DateTime = dateTime; 
     this.Millilitre = millilitre; 
    } 

    public string Remark { get; set; } 
    public DateTime DateTime { get; set; } 
    public Millilitre Millilitre { get; set; } 
} 

그러나 이로 인해 내 POCO가 다시 변경 될 수 있습니다. 누군가 그것을 사용하면 간단히 내가 원하는 와트가 아닌 어떤 속성을 변경할 수 있습니다.

  1. 내 자신의 데이터 액세스 레이어 쓰기 (또는 ORM 수정) 생성자를 사용하여 올바른 POCO 인스턴스를 만들 수 있도록 :

    지금까지 내가 그것을 볼 수 있듯이, 나는 두 가지 방법으로이 문제를 해결할 수 내가 만들었다.

  2. 매퍼 (mapper)를 만드십시오. ORM이 간단한 DTO 개체를 만들고 적절한 시간에 매퍼를 사용하여 DTO 개체를 내 POCO로 변환하도록합니다.

나는 해결책 2에 중점을 둡니다. 누군가이 방법에 대한 모범을 보았습니까? 아니면 누군가 내가 위에서 설명한 것보다 나은 해결책을 가지고 있습니까?

+0

# 2 가능성이 큽니다. automapper와 같은 구성 요소는 그 목적을 위해 유용 할 수 있습니다. 응용 프로그램의 어떤 클라이언트/레이어에서 유형을 변경 불가능하게해야합니까? –

+0

왜 데이터베이스 개체를 변경하지 않으시겠습니까? 질의를해도 문제가 없지만 데이터베이스의 값을 업데이트하는 방법은 무엇입니까? 나는 다음 사람처럼 불변 유형의 팬이다. 그러나 이것은 가변적 인 유형의 적절한 장소처럼 보인다. – Servy

+0

이 코드는 작은 취미 프로젝트의 샘플입니다. 새로운 주사를 추가 할 수 있음을 나타냅니다. 그러나 일단 추가되면 더 이상 수정할 수 없습니다. 물론 UI에서 코드를 작성할 수 있지만이 기능이 POCO에 표시되는지 훨씬 더 분명하게 드러납니다. – Sardaukar

답변

4

많은 OR/MS는 오랫동안 기본 생성자와 세터 (가 공용 또는하지 않은 경우, 그들은 단지 존재할 필요없이)

그래서 늘 일 (없는 기본 생성자)가로 일 :

를 이 작동하지만
public class InsulineInjection 
{ 
    public InsulineInjection(Millilitre millilitre, DateTime dateTime, string remark) 
    { 
     this.Remark = remark; 
     this.DateTime = dateTime; 
     _millilitre = millilitre; 
    } 

    public string Remark { get; set; } 
    public DateTime DateTime { get; set; } 
    public Millilitre Millilitre { get { return _millilitre; } } 
} 

또는이 (마지막 등록 정보에 대한 세터)

public class InsulineInjection 
{ 
    public InsulineInjection(Millilitre millilitre, DateTime dateTime, string remark) 
    { 
     this.Remark = remark; 
     this.DateTime = dateTime; 
     _millilitre = millilitre; 
    } 

    public string Remark { get; set; } 
    public DateTime DateTime { get; set; } 
    public Millilitre Millilitre { get { return _millilitre; } } 
} 

:

public class InsulineInjection 
{ 
    protected InsulineInjection() 
    { 
     // works with many OR/Ms 
    } 

    public InsulineInjection(Millilitre millilitre, DateTime dateTime, string remark) 
    { 
     this.Remark = remark; 
     this.DateTime = dateTime; 
     this.Millilitre = millilitre; 
    } 

    public string Remark { get; private set; } 
    public DateTime DateTime { get; private set; } 
    public Millilitre Millilitre { get; private set; } 
} 
+0

감사합니다. 마지막 예제가 OR/M에서 작동 할 수 있다는 것을 알지 못했습니다. – Sardaukar

2

모든 .NET ORM에서 데이터를 쓸 수있는 공용 속성 액세스가 필요한 것은 아닙니다. NHibernate는 private 필드 나 setter에 데이터를 쓰는 것을 지원합니다. 그러나 속성 이름에서 필드 이름을 추론 할 수 있도록 필드에 허용 된 명명 규칙 중 하나를 따라야합니다.

Check out NHibernate documentation about property mapping 특히 표 5.1을 참조하십시오. 접근 전략 및 표 5.2. 이름 지정 전략. nosetter 액세스 전략을보고 코딩 스타일에 맞는 이름 지정 전략을 선택하십시오. 생성자를 방지하기 위해

2

가 자신의 코드에 의해 사용되는, 당신은 당신이 실제로이 생성자를 호출하는 경우 컴파일러 오류를 얻을 것이다 속성에 통과 Obsolete attribute

[Obsolete("Default constructor only here for the ORM", true)] 
public InsulineInjection() {} 

true를 사용할 수 있습니다.

+0

또한 ORM에서 사용할 설정자가 있어야하며 노출하지 않으려는 설정자입니다. – Servy

+0

그 대답 – jeroenh

+0

에 대한 다른 답변보기 질문에 대한 답변을 게시 할 때 * 질문에 * 답하고 실제로 다른 대답에 의존해서 대답하지 않아야합니다. 기존 답변에 조금만 추가하려면 해당 답변 중 하나에 의견을 게시해야합니다. – Servy

0

이 시나리오는 기본적으로 dapper-dot-net으로 처리됩니다.

생성자 인수의 순서와 유형과 일치시키는 쿼리 필드의 순서와 유형 만 있으면됩니다.그래서 클래스의 쿼리처럼 뭔가 될 것이다 :

select millilitre, 
    ,dateTime 
    ,remark 
from injections 

불행하게도 말끔 밀리리터하는 소수 뭔가를 변환하는 방법을 알 수 없습니다.

관련 문제