2010-06-17 16 views
5

Eşleştirme yapılandırması için Psuedo kodu (aşağıdaki gibi) mümkün değildir, çünkü lambda yalnızca eşleme yaparken IDataReader, wheras türlerine erişmemize izin verir, AutoMapper her IDataRecord'ün her "hücresine" ulaşırken IDataReader.Read() == true:IDataReader'dan eşleme yaparken AutoMapper'ı özel sütun adlarından okuyacak şekilde yapılandırabilir miyim?

var mappingConfig = Mapper.CreateMap<IDataReader, IEnumerable<MyDTO>>(); 
mappingConfig.ForMember(
    destination => destination.???, 
    options => options.MapFrom(source => source.???)); 

Can Herkes, AutoMapper yapılandırmasını çalışma zamanında veya başka bir gereksinimi karşılayan başka bir dinamik yaklaşımı kullanarak bunu yapmanın bir yolunu düşünür.

Gereksinim, MyDTO özellik adlarıyla eşleşen sütun adlarına sahip olabilecek ve güvenebileceğim adlandırma kuralı bulunmayan gelen IDataReader'i desteklemektir. Bunun yerine, IDataReader.GetSchemaTable() ile IDataReader'de bulunan gerçek sütun adlarıyla beklenen sütun adlarını çapraz başvuruda bulunmalarını kullanıcıya sorarız.

cevap

3

bilmiyorum ama böyle ValueInjecter kullanarak nesnelere haritalama datareader değilim:

while (dr.Read()) 
{ 
    var o = new User(); 
    o.InjectFrom<DataReaderInjection>(dr); 
    return o; 
} 

ve DataReaderInjection (Automapper için ValueResolver gibi bir şey)

public class DataReaderInjection : KnownSourceValueInjection<IDataReader> 
    { 
     protected override void Inject(IDataReader source, object target, PropertyDescriptorCollection targetProps) 
     { 
      for (var i = 0; i < source.FieldCount; i++) 
      { 
       var activeTarget = targetProps.GetByName(source.GetName(i), true); 
       if (activeTarget == null) continue; 

       var value = source.GetValue(i); 
       if (value == DBNull.Value) continue; 

       activeTarget.SetValue(target, value); 
      } 
     } 
    } 

seni türlü nesnenin


Tamam bir IDataReader değerleri enjekte için kullanabilir, böylece edebilirsiniz göre req gereksinimleri, ben böyle olmalıyım:

public class DataReaderInjection : KnownSourceValueInjection<IDataReader> 
     { 
      protected override void Inject(IDataReader source, object target, PropertyDescriptorCollection targetProps) 
      { 
       var columns = source.GetSchemaTable().Columns; 
       for (var i = 0; i < columns.Count; i++) 
       { 
        var c = columns[i]; 

        var targetPropName = c.ColumnName; //default is the same as columnName 

        if (c.ColumnName == "Foo") targetPropName = "TheTargetPropForFoo"; 
        if (c.ColumnName == "Bar") targetPropName = "TheTargetPropForBar"; 
        //you could also create a dictionary and use it here 

        var targetProp = targetProps.GetByName(targetPropName); 
        //go to next column if there is no such property in the target object 
        if (targetProp == null) continue; 

        targetProp.SetValue(target, columns[c.ColumnName]); 
       } 
      } 
     } 
burada

Ben size enjeksiyona bazı şeyler geçirmek istiyorsanız, yapabileceğiniz, :)


Tamam istediğin gibi GetSchemaTable kullanılan burada
o.InjectFrom(new DataReaderInjection(stuff), dr); 
//you need a constructor with parameters for the DataReaderInjection in this case 

var ri = new DataReaderInjection(); 
ri.Stuff = stuff; 
o.InjectFrom(ri, dr); 
//you need to add a property in this case 

bir ipucu (parametreler yolu ile yapıcı için)

public class DataReaderInjection : KnownSourceValueInjection<IDataReader> 
    { 
     private IDictionary<string, string> stuff; 
     public DataReaderInjection(IDictionary<string,string> stuff) 
     { 
      this.stuff = stuff; 
     } 
        protected override void Inject(
... 
: bu birçok yönden işlem aşağıdaki gibi yapılır Çok ilginç bir cevap için
+0

+1. Bununla birlikte, henüz 'sütun' adını özellik adıyla eşleşecek şekilde beklediği için (henüz) gereksinimi karşılamamaktadır. Neyse, ValueInjecter'a geldiğiniz için teşekkürler. – rohancragg

+2

@rohancragg, nesneden (targetProps) tüm özellik adlarına sahip olursunuz ve datareader'dan (source.GetName (theName)) tüm isimleri alabilirsiniz, böylece gereksinimlerinize göre değiştirebilirsiniz. – Omu

+1

@rohancragg Düzenledim benim sorum, ben bu şekilde (Ben denedim yoktu, ama umarım öyledir) – Omu