2013-01-09 4 views
4

다음 코드를 사용하면 변수 유형에서받을 수있는 5 가지 유형이 있다고 가정합니다. 5 가지 조건문을 작성하는 대신 하나를 작성하고 "type"변수를 사용하여 모델이 무엇인지 지시하십시오 (이 경우 "CommentVote?"). 아니면이 "투표"모델을 가진 5 가지 각각으로 데이터 모델을 설계 한 방식의 결함입니까?중복 조건문을 사용하지 마십시오

if (type == "comment") 
{ 
     CommentVote voteObj = db.CommentVotes 
      .Where(x => x.UserID == UserID && x.CommentID == id) 
      .SingleOrDefault(); 
     if (voteObj != null) 
     { 
      voteObj.Vote = vote; 
      db.SaveChanges(); 
     } 
     else 
     { 
      CommentVote c = new CommentVote { 
       CommentID = id, UserID = UserID, Vote = vote, DateCreated = DateTime.Now 
      }; 
      db.CommentVotes.Add(c); 
      db.SaveChanges(); 
     } 

     count = (db.CommentVotes.Count(x => x.CommentID == id && x.Vote == true) - db.CommentVotes.Count(x => x.CommentID == id && x.Vote == false)); 
} 

매직 코드 : 내가 사랑 물건은 할 수있을합니다.

var modelName = ""; 
var modelOtherName = ""; 
if (type == "comment") { 
     modelName = CommentVote; 
     modelOtherName = CommentVotes; 
} 

     modelName voteObj = db.modelOtherName 
      .Where(x => x.UserID == UserID && x.CommentID == id) 
      .SingleOrDefault(); 

업데이트 : 내 모델이 울부 짖는 참조 읽기의 일부를 기반으로 쓰레기 수 있습니다 생각하기 시작하고있다. 그래서 나는 그 중 일부를 참조로 포함시키고 있습니다. 이것이 내가 해결하려고 노력해야하는 문제인지 알려주십시오.

public class CommentVote 
{ 
    public int CommentVoteID { get; set; } 
    public bool Vote { get; set; } 
    public DateTime DateCreated { get; set; } 
    public int UserID { get; set; } 
    public virtual User User { get; set; } 

    public int CommentID { get; set; } //This row changes from model to model 
    public virtual Comment Comment { get; set; } //This row changes from model to model 
} 

나는 거의 동일한 모델을 몇 개 가지고 있습니다.

+4

변경하려는 내용이 명확하지 않습니다. 이상적인 세계에서 당신이 원하는 것을 보여주는 마법의 발명 코드 (컴파일하지 않더라도)를 작성하여이 코드의 어떤 부분을 피하려고하는지 확인할 수 있습니다. 또한 다른 유형은 어떻게 다른가요? 코드가 완전히 다른가, 대부분 동일하거나, 거의 동일하거나, 정확히 동일하거나, 또는 무엇입니까? – Servy

+0

각 확장 객체 'type'에서 재정의 된 저장에 대한 공통 기능을 정의하기 위해 기본 클래스를 찾고 있다고 생각하십니까? 어쩌면 Table-Per-Type 패턴을 사용하고 있을까요? 위의 주석으로, 당신이 달성하고자하는 것을 짐작할 수있는 충분한 정보가 없습니다 ... – Matthew

+0

코멘트 주셔서 감사 드리며, 나는 "마법 코드"를 추가했습니다. @ 매튜, 나는 당신이 말한 것과 같은 일을하고 싶다고 생각하지만, 나는 아직도 많은 것을 배우기 때문에 당신이 말한 것이 무엇을 의미하는지 완전히 확신하지 못합니다. –

답변

1

동일한 작업을 수행하고 동일한 데이터를 설정한다고 가정하면 코드를 단일 명령문으로 완전히 줄일 수 있습니다. 이 경우 공통 작업 및 데이터가 포함 된 인터페이스와 해당 유형을 기반으로 올바른 객체를 인스턴스화하는 객체 팩터 리가 있어야합니다.

+0

트릭은 ORM이 여전히 쿼리를 수행 할 수있는 방식으로 처리합니다. – Servy

+0

이 대답은 semao가 기본 문제를 식별하는 데 도움이되는 반면 질문에 답합니다. 응답을 찾는 사람들은 Factory 패턴을 살펴보면 더 도움이 될 것입니다. –

2

내가 아는 한 더 많은 데이터베이스 아키텍처 관련.

투표의 종류가 (속성면에서)별로 다르지 않다면 다른 표를 사용하지 않을 것입니다. 대신 Type 열 및 (제공된 예제에서와 같이) CommentID에 대한 Nullable 열이있는 Vote 테이블을 하나 만듭니다.

그런 다음 클래스 상속을 사용하여 투표 (투표 기본 클래스 및 CommentedVote 자식 클래스)를 반영 할 수 있습니다.

Table Per Hierarchy Inheritance in Entity Framework

업데이트 : 최고의 모든 클래스에서 같은 propertieses를 반복하지 않는 것입니다. 당신은 다음과 같이 inharitence 사용

public abstract class Vote 
{ 
    public int VoteID { get; set; } 
    public bool isVote { get; set; } 
    public DateTime DateCreated { get; set; } 
    public int UserID { get; set; } 
    public virtual User User { get; set; } 

    public int VoteType { get; set;} //this property specifies type of vote (e.g. VoteType=1 for CommentedVote) 
} 
public class CommentVote : Vote 
{ 
    public int CommentID { get; set; } 
    public virtual Comment Comment { get; set; } 
} 
public class OtherVote : Vote 
{ 
    public int OtherID { get; set; } 
    public virtual Other Other { get; set; } 
} 

this 아주 좋은 블로그 게시물에서 당신은 모든 가능한 approches를 찾을 수 있습니다. 필자가 작성한 것은 테이블 계층 구조 (TPH)입니다.

+0

주목할만한 가치가 있습니다. 원본으로 사용하는 DB의 데이터를 수정할 수 없으면 각 테이블의 해당 열을이 논리 테이블로 연결하는 뷰를 데이터베이스 또는 저장 프로 시저에 만들 수 있습니다. – Servy

+0

데이터 모델에 대해 원하는 모든 작업을 수행 할 수 있습니다. 모델이 잘못 설계되어있을 수 있습니다. 이 기사를 읽으면 이해가되지 않습니다. 지금까지 모든 일은 엔티티 프레임 워크 코드에서부터 시작되었습니다. –

+0

@semao TPH를 사용했다고 가정 해 봅시다. 먼저 EF 코드에서 내 탐색 속성이 어떻게됩니까? 하나의 투표는 의견, 회신, 문서 등에 속할 수 있습니다. 탐색 속성이 필요한 경우도 있습니까? 모델 예제로 업데이트 된 질문을 참조하십시오. –

0

리플렉션을 사용하여 팩터 리 패턴을 구현하는 경우 매우 기본적인 예제는 shown here입니다.

간단히 말하면 다음과 같습니다. 5 가지 유형이있을 수 있으므로 각 인터페이스마다 5 가지 클래스를 작성해야합니다. 그런 다음 리플렉션을 사용하여 팩터 리 클래스를 생성하여 상황에 가장 적합한 클래스를 가져옵니다 (예제에서는 똑같은 클래스 이름을 사용하거나 클래스에 대한 속성은 here 등). 팩토리는 해당 인터페이스의 인스턴스를 반환합니다. 그러면 인터페이스에서 노출 된 메서드를 호출하여이 모든 작업을 수행합니다.

가장 중요한 부분은 다른 유형을 만들어야 할 경우 공장에서 검색 할 속성/이름을 가진 다른 클래스를 추가하는 것입니다. 다른 코드는 영향을받지 않아야하므로 열기/닫기 원칙을 준수하게됩니다.

+0

그는 여기서 ORM을 사용하고 있으므로 이러한 쿼리는 데이터베이스에 액세스하는 SQL 쿼리로 변환되고 메모리의 개체에 작용하지 않습니다. 따라서 쿼리 공급자가 데이터베이스 쿼리로 변환 할 수있을 정도로 똑똑해야하는 작업이 필요합니다. 반사는 (일반적으로) 해당 범주에 속하지 않습니다. – Servy

+0

그러나이 경우 데이터베이스 호출을 해당 클래스로 이동합니다. 나는 필요한 호출이 한 유형에서 다른 유형과 매우 다를 것이라고 가정하고 있습니다. – IronMan84

+0

Nope; 원하는 코드를보십시오. 그는 동일한 LINQ 쿼리를 수행하려고하지만 변수 테이블에서만 수행하려고합니다. 이론 상으로는 각각의 관련된 ORM 타입이 인터페이스를 구현하고,'IQueryable '를 초기화 한 다음 정적 쿼리를 수행 할 수 있습니다. 그러나 ORM이 그것을 지원할 지 알지 못합니다. 해야하고, 그렇지 않은 사람도 있습니다). – Servy

관련 문제