2012-02-17 5 views
0

여러 열 (예 : 관계형 데이터베이스)으로 구성된 테이블에 일부 값을 저장해야한다고 가정합니다 (예 : 첫 번째 열은 int, 두 번째 열은 string, 세 번째 열은 DateTime 등).테이블을 구현하려면 어떻게해야합니까?

하나 이상의 열이 기본 키와 같은 경우 이 기본 키 역할을하는 필드 집합이 될 IDictionary을 사용할 수 있습니다. 나머지 필드는 Value을 나타냅니다. 이 경우 하나 또는 두 개의 클래스/구조를 만들 수 있습니다. 기본 키는 단순히 기존의 유형입니다 예를 들어, 우리는 다음과 같이 클래스/구조체를 만들어야합니다 : 테이블이 다음이 될 수있는 동안

public class MyValue 
{ 
    public int Field1; 
    public double Field2; 
    public string Field3; 
} 

사전은 Dictionary<int, MyValue> 수 있습니다.

public class MyTable 
{ 
    private Dictionary<int, MyValue> _table; 
    ... 
} 

물론, 어플리케이션 도메인에 따라 상기 필드에 대한 범위 및/또는 유효 규칙이있을 수있다 : 예를 들어, Field1 긍정적으로 가질 수 있고, 등등 ...

로서 첫 번째 대안은 MyValue 클래스를 디자인하여 "규칙 위반"을 식별하기 위해 몇 가지 예외를 throw 할 수 있습니다. 그러나 아마도이 접근법은 과도 할 수도 있습니다. 특히 MyValue 클래스가 내부적으로 MyTable에 사용되는 경우이 경우에는 다음과 같은 코드를 작성하고 유효 기간 오류 MyTable 클래스를 처리합니다. 즉, MyTable 클래스는 데이터 필드를 삽입하기 전에 검사합니다. 사전에, 그래서 MyValue은 "바보"클래스 ...

namespace MyNamespace 
{ 
    class MyValue 
    { 
     // only public fields 
    } 

    public class MyTable 
    { 
     private Dictionary<int, MyValue> _table; 
     ... 

     public void Add(int key, int field1, double field2, string field3) 
     { 
      // some code to check validity range for fields 
      ... 
     } 
    } 
} 

이 솔루션은 정확 것입니까? 아니면이 접근법을 피해야합니까? 난 항상 예외, GetHashCode 방법을 Equals 처리 (완전한 방식으로 클래스/구조체를 정의해야 하는가?

+2

이것은 너무 광범위하여 어디서부터 시작해야할지 모릅니다. – cadrell0

+0

예, 유효한 해결책입니다. –

+0

.NET에 대한 몇 가지 디자인 지침 (이 질문과 관련된)에 대한 링크가 있습니까? – enzom83

답변

2

나는 그 값들이 그들 자신의 일관성을 점검하도록 할 것이다. 필드를 속성으로 구현하면 setter는 검사를 수행하고 값이 범위를 벗어나는 경우 예외를 발생시킬 수 있습니다.

또한 다소 유연한 접근 방식을 제안합니다.테이블 레코드가 구현해야하는 인터페이스를 정의하십시오.

public interface IRecord<PK> 
{ 
    PK ID { get; } 
} 

레코드에는 기본 키로 사용할 ID가 있어야합니다. 일반 기본 키 유형 PK을 사용합니다. 당신이 볼 수 있듯이

이제 그것은 IRecord<int>를 구현하고 IDField1를 반환,이

public class MyValue : IRecord<int> 
{ 
    private int _field1; 
    public int Field1 
    { 
     get { return _field1; } 
     set 
     { 
      if (value < 0 || value > 1000) { 
       throw new ArgumentException("Value of 'Field1' must be between 0 and 1000"); 
      } 
      _field1 = value; 
     } 
    } 

    public double Field2; 

    #region IRecord<int> Members 

    public int ID { get { return Field1; } } 

    #endregion 
} 

같은 값 클래스를 정의 할 수 있습니다. Field1은 전달 된 값을 검사합니다. 기본 키가 여러 필드로 구성된 경우 기본 키 유형으로 Tuple (.NET 4.0)과 같은 유형을 사용할 수 있습니다. IRecord<Tuple<int,double>>처럼. , 또는

당신은 기록이 명시 적으로 구현 할 수 있습니다 :

이제 당신은 당신이

public class MyTable : Table<MyValue, int> 
{ 
} 

UPDATE와 같은 특정 테이블을 정의 할 수있는 일반적인 테이블

public class Table<T, PK> 
    where T : IRecord<PK> 
{ 
    private Dictionary<PK, T> _table = new Dictionary<PK, T>(); 

    public void Add(T item) 
    { 
     _table.Add(item.ID, item); 
    } 
} 

를 정의 할 수 있습니다 오류 처리

public interface IRecord<PK> { 
    PK ID { get; } 

    bool IsValid { get; } 
    string[] Errors { get; } 
} 
4

를 당신이 무슨 짓을했는지 것은 부서지기 쉬운, 지나치게 복잡한 모양과 궁극적으로 유지 보수 악몽으로 이어질 것입니다.

내가 좋겠 두 가지 옵션이 있다고

옵션 중 하나 :... 그것은 실제 데이터베이스에서 백업 할 필요가 없습니다 DataTable을 사용하고 당신이 그것을 실행시 (열 정의를 포함) 레이아웃의 정의 할 수 있습니다

옵션 2 : "레코드"논리를 구현하는 클래스를 정의하십시오. 해당 클래스를 보유 할 컬렉션을 정의하십시오. LINQ를 사용하여 필요에 따라 컬렉션을 "쿼리"하십시오.

두 가지 옵션의 주된 차이점은 DataTable이 사용할 수있는 규칙 유형이 매우 제한되어 있다는 것입니다. 옵션 2 인 OTOH를 사용하면 원하는 것을 정확하게 구축 할 수 있습니다.

+0

_ "기록"논리를 구현하는 클래스를 정의하십시오. 기본적으로이 클래스는 public 필드의 단순한 "집합"이어야합니다. 정확합니까? – enzom83

+0

+1. * 왜 그런 생각을 전혀하지 않습니까? 데이터베이스 백엔드가 없습니까? 관계형 데이터베이스 무결성 및 비즈니스 규칙에 대한 통합 된 필드 이론 작업? 그럼에도 불구하고 * 왜 * 바퀴를 재발견합니까? – radarbob

관련 문제