2009-11-18 2 views
3

여기에 거래가 나와 있습니다.오토 맵퍼, 제네릭, 기능 시간표

사용자가 미리 정의 된 데이터 세트를 기반으로 보고서를 작성할 수있는 보고서 디자이너가 있습니다. 보고서에 포함 할 열 집합을 선택한 다음 보고서가 실행될 때 automapper를 사용하여 NHibernate 컬렉션을 dto 클래스 컬렉션에 매핑하여 IList를 만듭니다.

이 문제는 DTO 컬렉션에 필요 여부에 관계없이 모든 데이터가 채워지면서 중복 된 열이로드된다는 점에서 문제가 있습니다.

이 문제의 해결책은 무엇입니까? 왜 우리가 가지고있는 정보를 사용하여 런타임에 DTO 유형을 작성하고 필요한 경우에만 속성을 사용하여 동적으로 생성 된 DTO 컬렉션에 NHibernate에 수집을 매핑하지 :

#region create a dto type: 
      AssemblyName assemblyName = new AssemblyName(); 
      assemblyName.Name = "tmpAssembly"; 
      var assemblyBuilder = System.Threading.Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); 
      ModuleBuilder module = assemblyBuilder.DefineDynamicModule("tmpModule"); 

      // create a new type builder 
      TypeBuilder typeBuilder = module.DefineType("ReportDto", TypeAttributes.Public | TypeAttributes.Class); 

      foreach (var propertyName in propNames) 
      { 

       // Generate a private field 
       FieldBuilder field = typeBuilder.DefineField("_" + propertyName, typeof(string), FieldAttributes.Private); 
       // Generate a public property 
       PropertyBuilder property = 
        typeBuilder.DefineProperty(propertyName, 
            PropertyAttributes.None, 
            typeof(string), 
            new Type[] { typeof(string) }); 

       // The property set and property get methods require a special set of attributes: 

       MethodAttributes GetSetAttr = 
        MethodAttributes.Public | 
        MethodAttributes.HideBySig; 

       // Define the "get" accessor method for current private field. 
       MethodBuilder currGetPropMthdBldr = 
        typeBuilder.DefineMethod("get_value", 
               GetSetAttr, 
               typeof(string), 
               Type.EmptyTypes); 

       // Intermediate Language stuff... 
       ILGenerator currGetIL = currGetPropMthdBldr.GetILGenerator(); 
       currGetIL.Emit(OpCodes.Ldarg_0); 
       currGetIL.Emit(OpCodes.Ldfld, field); 
       currGetIL.Emit(OpCodes.Ret); 

       // Define the "set" accessor method for current private field. 
       MethodBuilder currSetPropMthdBldr = 
        typeBuilder.DefineMethod("set_value", 
               GetSetAttr, 
               null, 
               new Type[] { typeof(string) }); 

       // Again some Intermediate Language stuff... 
       ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator(); 
       currSetIL.Emit(OpCodes.Ldarg_0); 
       currSetIL.Emit(OpCodes.Ldarg_1); 
       currSetIL.Emit(OpCodes.Stfld, field); 
       currSetIL.Emit(OpCodes.Ret); 

       // Last, we must map the two methods created above to our PropertyBuilder to 
       // their corresponding behaviors, "get" and "set" respectively. 
       property.SetGetMethod(currGetPropMthdBldr); 
       property.SetSetMethod(currSetPropMthdBldr); 
      } 

      Type generetedType = typeBuilder.CreateType(); 

      // Now we have our type. Let's create an instance from it: 
      object generetedObject = Activator.CreateInstance(generetedType); 

      #endregion 


      Mapper.CreateMap(typeof(MainInvoiceDataSums), generetedType); 
      var dto = 
       Mapper.Map<IList<MainInvoiceDataSums>, IList<generetedType>>(r); 

문제를?

var dto = 
       Mapper.Map<IList<MainInvoiceDataSums>, IList<generetedType>>(r); 

우리는 할 수없는 일반 매개 변수로 생성 된 형식을 사용하여 IList의 최대 새로운 :의

난 항상이 같은 문제로 실행하는 것. 제가 제네릭을 학대합니까? 이것이 가능한가? 그것은 애플 리케이션을 훨씬 더 빠르게 만들 것입니다 (캐싱과 재생성 될 temp 어셈블리를 불투명하게하는 몇 가지 검사가 추가됨). 그리고 유지 보수가 훨씬 덜 까다 롭습니다.

와트 : //

우리는 일반 매개 변수로 생성 된 형식을 사용하여 IList의를 북동 수 없습니다의

난 항상이 같은 문제로 실행하는 것. 제가 제네릭을 학대합니까? 이것이 가능한가? 그것은 애플 리케이션을 훨씬 더 빠르게 만들 것입니다 (캐싱과 재생성 될 temp 어셈블리를 불투명하게하는 몇 가지 검사가 추가됨). 그리고 유지 보수가 훨씬 덜 까다 롭습니다.

w : //

답변

2

got it !!

일반 목록을 전달하는 데 createmap을 사용하지 마십시오!

MethodInfo createMap = createMapInfo.MakeGenericMethod(new Type[] { typeof(MainInvoiceDataSums), generetedType }); 

정렬 됨 !!

:

와트 : //

+0

답변으로 표시해야합니다. – Fenton

2

왜지도의 비 일반 버전을 사용할 수 있습니까?

Mapper.Map(r, typeof(IList<MainInvoiceDataSums>), 
         typeof(IList<>).MakeGenericType(new [] { generatedType });