2011-10-29 2 views
1

현재 MySQL 및 MSSQL 데이터베이스를 지원하는 C# 응용 프로그램을 만들고 있습니다. 내가 겪고있는 문제는 내 포장지에 있습니다. MySQL 용으로 작업하는 코드가 있지만 여러 데이터베이스를 지원하도록 수정하는 데 문제가 있습니다.여러 데이터베이스를 지원하는 C# DB 래퍼

내 코드를 제거한 버전을 살펴보면 DBMySQL 유형의 dbConn 객체가있는 것을 볼 수 있습니다.이 객체는 MySQL 지원 만 원하는 경우에 적합합니다. dbConn = new DBMySQL (...) 및 dbConn = DBMSSQL (...)을 실행할 수 있도록 dbMySQL을 수정해야하며 dbconn.SomeMethod()를 호출하고 해당 데이터베이스에서 작업하도록 할 수 있습니다. . 데이터베이스와 특정 오류 검사에 일괄 적으로 삽입하기 위해 DBMySQL 및 DBMSSQL 클래스에 다른 것들이 있으므로 최대한 동일한 설정을 유지하는 것이 좋습니다.

Object dbConn과 같은 것을 선언하려고 시도했으나이를 조작했지만 그렇게 잘 진행되지 않았습니다. 그런 다음 객체 유형의 열거 형 클래스를 사용하려고했지만 그 문제도있었습니다. 이 모든 작업을 수행하는 타사 라이브러리가 많이 있지만 자체 코드를 사용하는 것이 좋습니다.

이 문제를 해결하기 위해 DBWrapper를 수정하는 방법에 대한 제안 사항이 있습니까? 이 게시물을보기 및 아이디어가 그래서 만약 내가 전혀 도움을 주셔서 감사 것이이 시점에서

//WRAPPER CLASS THAT CALLS DBMySQL, ISSUE IS I NOW NEED TO SUPPORT 
//DBMSSQL as well, not just DBMySQL 
class DBWrapper 
{ 
    DBMySQL dbConn; 

    public DBWrapper(...,string type) 
    { 
     if(type.Equals("MySQL") 
     { 
      dbConn = new DBMySQL(...); 
     } 
     //NEED TO REWORK TO SUPPORT THIS BELOW!! 
     else if(type.Equals("MSSQL") 
     { 
      //NEED TO MODIFY TO SUPPORT MSSQL 
      //ISSUE IS DbConn is of type DBMySQL 
      //SO I CANNOT GO 
      // DbConn = new DBMSSQL(...); 
      // any ideas? 
     } 
    } 

    public void setQuery(string myquery) 
    { 
      dbConn.setQuery(myquery); 
    } 
} 

class DBMySQL 
{ 
    public string dbinfo; 
    string query; 

    public DBMySQL(...) 
    { 
     dbinfo = ...; 

    } 

    public void setQuery(...) 
    { 
     query = myquery; 
    } 
} 

//NEED TO RE-WORK WRAPPER TO SUPPORT THIS 
class DBMSSQL 
{ 
    public string dbinfo; 
    string query; 

    public DBMSSQL(...) 
    { 
     dbinfo = ...; 

    } 

    public void setQuery(...) 
    { 
     query = myquery; 
    } 
} 

, 나는 이미이 모든 일을 보냈습니다으로 알려 주시기 바랍니다.

+0

이 문제는 Factory Method 디자인 패턴을 사용하여 해결할 수 있습니다. [여기] (http://en.wikipedia.org/wiki/Factory_method_pattern) – sll

답변

6

필요한 것은 데이터 액세스 클래스가 원하는 것을 설명하는 인터페이스를 만드는 것입니다.

예. 당신이보고에서을 제안하는 것이 유용 할 수 없습니다

IDBAccess dbConn; 
dbConn = new DBMySQL(); 
dbConn = new DBMSSQL(); 

마음에 갖는이 새로운 것을 :이 시점에서 샘플

public interface IDBAccess 
{ 
    void setQuery(...); 
} 

public class DBMySQL : IDBAccess 
{ 
    public string dbinfo; 
    string query; 

    public DBMySQL(...) 
    { 
     dbinfo = ...; 

    } 

    public void setQuery(...) 
    { 
     query = myquery; 
    } 
} 

public class DBMSSQL : IDBAccess 
{ 
    public string dbinfo; 
    string query; 

    public DBMSSQL(...) 
    { 
     dbinfo = ...; 

    } 

    public void setQuery(...) 
    { 
     query = myquery; 
    } 
} 

에서이 작업을 수행 할 수있을 것입니다 NHibernate 또는 Castle ActiveRecordCastle Windsor입니다. 그러나 미래에 그들을 염두에 두라.

+0

고마워요! 이것은 내가 필요한 것입니다. 나는이 인터페이스에 대해 더 자세히 살펴볼 예정이다. 꽤 좋은 생각이다. – user1020184

+0

예, 객체 지향 프로그래밍 개념을 조사해야합니다. http://msdn.microsoft.com/en-us/library/ms173156.aspx 및 http://msdn.microsoft.com/en-us/library/ms173152.aspx를 참조하십시오. –

2

두 데이터베이스를 모두 처리하는 큰 클래스를 만들지 마십시오. 랩퍼 IDBWrapper에 대한 공통 인터페이스를 작성한 다음 각 데이터베이스에 대해 별도의 구현을 작성해야합니다.

그런 다음 올바른 구현을 선택할 수있는 논리를 만들 수 있습니다. 래퍼가 필요할 때마다 다음과 같이 작성하고 싶지는 않습니다.

IDBWrapper db = (useMySQL ? new MySqlDBWrapper(...) : new MsSqlDBWrapper(...)); 

두 가지 옵션이 있습니다. 추상 팩토리를 사용할 수는 있지만 실제로 데이터베이스 래퍼 생성을 추상화하는 모든 것이 작동합니다.

+0

나는 C#을 처음 사용하고 배우기를 배우기 때문에 아직 익숙하지 않습니다. 외국이지만 내 주변 정보를 알려주고 좋은 링크가 있으면 알려주세요. 조언 해주셔서 감사합니다. – user1020184

0

내 머리 꼭대기에서 생각할 수있는 하나의 빠른 해킹은 사용자가 선택한 것을 기반으로 하나의 거대한 클래스를 만들고 해당 개체와 클래스를 사용합니다. 또한 각 데이터 소스에 대해 여러 클래스를 만든 다음 사용자가 선택한 것을 기반으로 올바른 데이터 소스 공급자 클래스로 다시 라우팅하는 하나의 랜딩 클래스를 만들 수 있습니다. 별로 좋지는 않지만 작동 할 수있는 것은 ...

2

C#에서 데이터베이스 계층을 다시 구현해야하는 특별한 이유가 있습니까? 당신은 말하기를 들여다 보았습니까? Entity Framework, NHibernate 또는 다른 .NET ORM?구현 세부 사항에 대해 너무 많이 걱정할 필요없이 모든 데이터 액세스를 훌륭하게 마무리합니다. 또한 표를 클래스에 매핑하는 등 다른 장점을 제공합니다 (예 : 표에있는 내용과 다른 방식을 기반으로 클래스를 채 웁니다), 캐싱 및 기타 다양한 기능.

직접 작성하려는 경우 인터페이스를 선언하고 모든 데이터베이스 연결을이 인터페이스에서 상속받으며 인터페이스 인스턴스의 등록 정보에 연결 인스턴스를 저장해야합니다. 예 :

public interface IDatabaseConnection 
{ 
    void setQuery(string myQuery); 
} 

public class DBWrapper 
{ 
    private IDatabaseConnection Connection { get; set; } 

    public DBWrapper(string type) 
    { 
     if(type == "MySql") 
      Connection = new DBMySQL(); 
     else if(type == "MsSql") 
      Connection = new DBMSSQL(); 
    } 
} 

public class DBMySQL : IDatabaseConnection 
{ 
    ... 
} 

public class DBMSSQL : IDatabaseConnection 
{ 
    ... 
} 
+0

내가 ' 이전에 링크 한 두 가지를 보았습니다. 처음부터 모든 것을 구축하여 내 자신의 소프트웨어를 설계하는 방법에 대해 더 배울 수 있기를 바랍니다. 그래서 정말 배움의 경험입니다. 당신의 대답은 방금 전에 몇 분 전에 게시 된 것과 비슷합니다. 나는 두 가지를 정답으로 선택할 수 있었지만 도움을 주셔서 감사합니다. – user1020184

+0

걱정하지 마라. 원래는 인터페이스 기반 솔루션을 게시하려고 했었지만, ORM, 엔티티 프레임 워크 및 NHibernate에 대해 알고 있는지, 그리고 많은 기능을 제공하므로 앞으로도 읽을 가치가 있고 사용하기에 충분한지 확인하기로 결정했다. 기능 및 빌드 할 수있는 아주 좋은 프레임 워크를 제공합니다. 학습 경험으로서 스스로를 구축하는 데 아무런 해가 없습니다. 특히 나중에 '자신의 것'(Entity Framework/NHibernate)과 비교하고 학습 경험으로 활용할 경우 특히 그렇습니다. –

1

또한 일반 저장소 패턴과 해당 데이터베이스에 대한 ORM을 살펴볼 수도 있습니다.

+0

나는 그걸 지금보고있다. 고마워, 미래에 도움이 될 것 같아. – user1020184

1

는 ADO.NET에서 모든 연결 클래스는 그래서 당신이 원하는하는 것은 실제로 .NET에 내장되어, System.Data.Common.DbConnection에서 상속 - 당신이해야 할 모든 대신 SqlConnection/MySqlConnectionDbConnection에서 연결을 저장하고를 사용하는 것입니다 클래스는 System.Data.Sql/MySql/이 아닌 System.Data.Common에 있습니다.

여기서 볼 수있는 주요 문제는 단순한 선택 및 삽입 외에도 실제 SQL 표준이 없다는 것입니다. SqlServer 및 MySql 쿼리에 대해 다른 구문이 필요합니다. 이 문제를 해결하려면 Linq to SQL (라이브러리에 의존하고 싶지 않은 경우 많은 작업) 또는 래퍼 만 수행하려는 경우 특정 작업 - 사전을 가질 수 있습니다. 각 데이터베이스에 대해 해당 작업의 준비 템플릿 (String.Format)을 저장하고 런타임에 해당 작업을 수행하는 래퍼 메서드에 적용합니다.