2013-08-25 1 views
1

"type"을 데이터베이스에 표시하는 좋은 방법은 무엇입니까?데이터베이스의 클래스 유형을 저장하는 가장 좋은 방법은 무엇입니까?

나는 수많은 하위 클래스에 의해 상속되는 기본 클래스 Action을가집니다. Action에는 Id, Name 등의 멤버가 있으며 모두 action이라는 데이터베이스의 테이블에있는 해당 열에 해당합니다. 그래서 action 테이블은 다음과 같습니다

id | name | type 

type 열은 그것이 어떤 조치를 의미한다. 내 코드에서는 부모 Action에서 파생 된 하위 클래스에 해당합니다. 이제 유형의 유형을 데이터베이스유형 필드에 저장하려면 어떻게해야합니까?

db의 유형 열은 모든 데이터 유형이 될 수 있습니다.

옵션 : DB에 문자열로

  1. 저장 action.GetType().ToString(). 리플렉션을 사용하여 유형의 문자열 표현을 원래 유형으로 변환하여 db에서 액션 유형을 가져옵니다. 앞으로 클래스 이름이 변경되면 문제가 될 것입니다.

  2. 각 하위 클래스를 의미하고 TypeAttribute하여 장식하는 열거를 생성, 뭔가 같은 : 내가 열거를 만들 필요가 이후 여기에서

    public abstract class Action 
    { 
        public enum Kind 
        { 
         [Type(typeof(ControlAction))] 
         ControlAction = 1, 
    
         [Type(typeof(UpdateAction))] 
         UpdateAction = 2, 
    
         etc 
        } 
    
        public abstract Kind ActionType { get; } 
    } 
    
    public class ControlAction : Action { public override Kind ActionType { get { return Kind.ControlAction; } } } 
    public class UpdateAction : Action { public override Kind ActionType { get { return Kind.UpdateAction; } } } 
    //etc 
    

    이 각 클래스에 대한 것을 제외하고, 좋아 보인다 . 그리고 끝내야 할 일이 너무 많다.

  3. 클래스를 int 값과 연결하는 별도의 정적 해시 테이블 <int, Type>을 작성하십시오. 약간 읽을 수 있습니다.

이에 대한 더 나은 솔루션이 있습니까?

+0

ORM을 만드시겠습니까? 또는 다른 응용 프로그램에서 재사용 할 수있는 데이터베이스에 클래스 유형 정보가 필요합니다 (아마도 가장 중요한 경우). – edsioufi

+0

@edsioufi 아니오, 이것은 orm에 관한 것이 아닙니다. 'ControlAction','UpdateAction' 등의 각 자식 액션은 클라이언트가 생성 한 액션입니다. 각 액션 유형에는 클라이언트가 필요로하는 고유 한 정보 집합이 있습니다. 이제는 클라이언트가 데이터베이스에 작성한 작업을 저장하는 방법이 필요합니다. 나중에 db에서 이러한 다양한 액션을로드 할 때, 나는'UpdateAction'에서'ControlAction'을 분리해야합니다. – nawfal

답변

1

나는 옵션 2를 사용하여 종료하지만, 속성의 덜 혼란과. 이런 식으로 뭔가 : 이것에 대한

public abstract class Action 
{ 
    public enum Kind 
    { 
     ControlAction = 1, 

     UpdateAction = 2, 

     etc 
    } 

    public abstract Kind ActionType { get; } 
} 

public class ControlAction : Action { public override Kind ActionType { get { return Kind.ControlAction; } } } 
public class UpdateAction : Action { public override Kind ActionType { get { return Kind.UpdateAction; } } } 

가장 큰 장점은 (더 입력을 의미하는 경우에도) 그이다, 는 숫자 값을 적용은 클래스 타입과 연관 될 수 있습니다. int로

이제 클래스는입니다 : 매우 빠른

var value = (int)instance.ActionType; 

.

하지만 int를 클래스 인스턴스 (또는 클래스 유형)로 변환하려면 각 하위 작업 유형의 인스턴스를 만들고 입력 된 int 값과 일치하도록 ActionType 속성을 비교해야합니다. 이것은 느려질 것입니다. 그러나 나는 일종의 캐시를 만들어 그것을 더 빨리 만들 수 있습니다. 식으로 뭔가 :

static readonly Dictionary<Action.Kind, Type> actionTypes = 
    GetDefaultInstanceOfAllActions().ToDictionary(x => x.ActionType, x => x.GetType()); 
public static Action ToAction(this Action.Kind value) 
{ 
    return (Action)Activator.CreateInstance(actionTypes[value]); 
} 

GetDefaultInstanceOfAllActions는 일부 반사를 (한 번) 행동 (나는 그것에 대해 this answer 같은 것을 사용)의 모든 유형을 얻을 않습니다.난 going the expression route.

이점에 의해 인스턴스화 빠르게 메이크업을 할 수 있습니다 :

  1. 덜 번거 로움을 새로운 최고 (특성)을 만들 때.

  2. 클래스 유형에 int를 적용하도록합니다.

  3. 적절한 캐싱을 통해 보통 빠릅니다.

2

제 3의 해시 테이블에서 해시 테이블을 사용하면 설계가 더 명확 해 보입니다. 그리고 나는 그 관리를 데이터베이스에 위임 할 것이다!

어쨌든 관계형 데이터베이스가 가장 뛰어나며 두 엔티티 (당신의 경우, 행동 및 유형) 간의 관계를 생성하지 않는가? 다른 장점은 정규화 된 스키마로 끝나는 것입니다. (실제로는 형식 테이블에 이름이 있지만 이제는 정규화를 사용하면 나중에 필요할 때 형식에 특성을 쉽게 추가 할 수 있습니다. 이것이 디자인으로서 더 깨끗한 이유입니다).

스키마는 다음과 같이 될 것이다 :

작업 테이블

action_id(PK) | name | type_id (int, FK to Type table) 

유형 테이블

type_id(PK) | type_name 

지금 당신이 안전한지에 클래스 변경의 이름 미래 (문자열 유형의 첫 번째 제안에서 우려). 사실, 당신이 할 수있는 모든는 보유하지 않는 한, 여기에 (문제를 해당 Type 테이블 행에 type_name 값을 변경하지 않고 모든 Action 행이 여전히 변경 한 번 생성하지 type_id에 의해이 행에 링크 될 것입니다 모든 "비즈니스 의미").

그리고 해시 테이블의 키합니다 (type_id PK)을 관리 할 수있는 RDMBS의 책임입니다 당신이 읽을 수있는 형식으로 3합니다 (Type 테이블)에서 해시 테이블이 있습니다. 당신이 type_id 컬럼에 대응하는 int 값으로 클래스를 묶어해야하지만, 오히려 클래스 유형 (type_name)에 대해 그것을 찾는하여 Type 테이블 type_id에서 가져 오지 않습니다

참고.

+2

또한 ActionType으로 문자열을 사용하고 actionType이 이미 있으면 Type 테이블을 확인하고 대신 id를 사용하십시오 (그렇지 않은 경우 형식 테이블에 추가). 캐시와 같은 것을 만들 수 있습니다 (사전 ). actiontype 이드의 이름) –

+0

@edsioufi, 클래스 이름이 바뀌면 어떻게 도움이되는지 잘 모르겠습니다. 타입 테이블에서'type_name'으로 들어가야 할 것은 무엇입니까? 제로 엔이 좋은 지적 이네, 그게 니가 의미하는거야? – nawfal

+0

아니, 편집 한 것 같아. 유형 테이블에서 유형 조회를 수행하려면 어떻게해야합니까? 'type_name'이 클래스의'Type'의 문자열 표현 일 뿐이라면, 작동하지 않을 것입니다. – nawfal

0

나는 첫 번째 옵션을 사용 반사와 함께 갈 것입니다. 기존 클래스 이름을 변경하는 대신 새 액션 유형을 추가하기를 원할 가능성이 높습니다. 따라서 리플렉션을 사용하여 유형을 쉽게 직렬화하는 것이 더 유용합니다. 그러면 작업을 직렬화하고 유형 문자열에서 복원하는 유틸리티 클래스를 가질 수 있습니다.

+0

클래스 이름이 변경 될 수 있습니다. 나는 그것을 책임지고 있지 않다. 미래의 개발자들은 아무렇지도 않게 잡혀서는 안됩니다. 또한 나는 연재하지 않는다. – nawfal

관련 문제