2011-03-13 4 views
0

C#에서 제네릭을 사용하기 시작했습니다. 예를 들어 내가 한 것은 일반적인 메소드를 구현하는 추상 클래스가 있다는 것입니다. 이러한 일반 메서드는 SQL 쿼리, 연결 문자열 및 Type T를 매개 변수로 취한 다음 데이터 집합을 구성하고 개체를 채우고 다시 반환합니다. 이렇게하면 각 Business Object에는 데이터를 채우거나 데이터 세트를 작성하는 메소드가있을 필요가 없습니다. 우리가해야 할 일은 타입, SQL 질의, 연결 문자열을 전달하는 것입니다. 나머지는이 메소드가 수행합니다. 코드 샘플을 여기에 제공하고 있습니다. 나는 내가 한 일에 대해 더 나은 해결책을 가지고있는 사람들과 토론하기를 기대하고있다.C#의 제네릭 사용

 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Data; 
using System.Data.SqlClient; 
using MWTWorkUnitMgmtLib.Business; 
using System.Collections.ObjectModel; 
using System.Reflection; 

    namespace MWTWorkUnitMgmtLib.TableGateway 
    { 
    public abstract class TableGateway 
    { 
     public TableGateway() 
     { 

     } 

     protected abstract string GetConnection(); 
     protected abstract string GetTableName(); 

     public DataSet GetDataSetFromSql(string connectionString, string sql) 
     { 
      DataSet ds = null; 
      using (SqlConnection connection = new SqlConnection(connectionString)) 
      using (SqlCommand command = connection.CreateCommand()) 
      { 
       command.CommandText = sql; 
       connection.Open(); 
       using (ds = new DataSet()) 
       using (SqlDataAdapter adapter = new SqlDataAdapter(command)) 
       { 
        adapter.Fill(ds); 
       } 
      } 
      return ds; 
     } 

     public static bool ContainsColumnName(DataRow dr, string columnName) 
     { 
      return dr.Table.Columns.Contains(columnName); 
     } 

     public DataTable GetDataTable(string connString, string sql) 
     { 
      DataSet ds = GetDataSetFromSql(connString, sql); 
      DataTable dt = null; 
      if (ds != null) 
      { 
       if (ds.Tables.Count > 0) 
       { 
        dt = ds.Tables[0]; 
       } 
      } 
      return dt; 
     } 

     public T Construct(DataRow dr, T t) where T : class, new() 
     { 
      Type t1 = t.GetType(); 
      PropertyInfo[] properties = t1.GetProperties(); 

      foreach (PropertyInfo property in properties) 
      { 
       if (ContainsColumnName(dr, property.Name) && (dr[property.Name] != null)) 
        property.SetValue(t, dr[property.Name], null); 
      } 

      return t; 
     } 

     public T GetByID(string connString, string sql, T t) where T : class, new() 
     { 
      DataTable dt = GetDataTable(connString, sql); 
      DataRow dr = dt.Rows[0]; 
      return Construct(dr, t); 
     } 

     public List GetAll(string connString, string sql, T t) where T : class, new() 
     { 
      List collection = new List(); 
      DataTable dt = GetDataTable(connString, sql); 
      foreach (DataRow dr in dt.Rows) 
       collection.Add(Construct(dr, t)); 

      return collection; 
     } 
    } 
}
+4

나는 이것이 StackOverflow.com에 대한 질문이라고 생각한다. – Guillaume86

답변

1

당신은 생성하고 속성을 설정하는 대표를 캐싱하여 perfs을 향상시킬 수 있습니다 :

public static class Utils 
{ 
     public static Action<T, object> MethodDelegateFor<T>(MethodInfo method) 
     { 
      var parameter = method.GetParameters().Single(); 
      var instance = Expression.Parameter(typeof(T), "instance"); 
      var argument = Expression.Parameter(typeof(object), "argument"); 
      var methodCall = Expression.Call(
       instance, 
       method, 
       Expression.Convert(argument, parameter.ParameterType) 
       ); 
      return Expression.Lambda<Action<T, object>>(
       methodCall, 
       instance, argument 
       ).Compile(); 
     } 

     public static Action<T, object> PropertySetterFor<T>(PropertyInfo property) 
     { 
      return MethodDelegateFor<T>(property.GetSetMethod()); 
     } 
} 

사용 :

var propSetter = Utils.PropertySetterFor<T>(yourPropInfo); 
propSetter(newInstance, theValue); 
+0

guillaume, 정확하게 코드가 무엇인지 설명해 주시겠습니까? 이렇게하는 것의 이점은 무엇입니까? –

+0

간단한 리플렉션 (캐시 및 여러 번 재사용하는 경우)보다 훨씬 빠르게 개체의 속성을 설정할 수있는 대리자를 만듭니다. Jon Skeet의 블로그 게시물 (http://msmvps.com/blogs/jon_skeet)에서 영감을 얻었습니다. 실제 세계 예제가 필요한 경우이 라이브러리에 의해 사용됩니다 : https://github.com/JeremySkinner/WebMatrix.Data. /archive/2008/08/09/making-reflection-fly-and-exploring-delegates.aspx – Guillaume86

+0

강력하게 형식화/blob/master/src/WebMatrix.Data.StronglyTyped/PropertyMetadata.cs – Guillaume86

0

단위를 사용하는, 내가 믿는, 더 강력한 것 작업 패턴을 저장소 패턴과 함께 사용하지만 일반적인 예로 수정되었습니다.

그렇다면 완전히 기능하는 CRUD를 구축 할 수 있습니다. "특수한"것에 대한 다형성을 사용하려면 전문화가 필요합니다.

또한 엔티티 프레임 워크를 사용하여 이전 SQL 명령을 전환합니다. 작업 부하를 상당히 줄여줍니다.

내가 그랬을 것이다.

관련 문제