2013-02-11 25 views
1

由于遗留原因,我不得不调用ASMX Web服务,它给我一个DataTable而不是一个实体,然后将数据表传递回Web服务。我在这里使用术语实体,但没有ORM,因为整个数据层(CRUD)由这些Web服务完成。我简单地调用了一个Web方法,该方法给了我一个数据表,将此数据表转换为实体,更新实体,将其转换回数据表,最后将此数据表传递给Web方法。将实体/模型转换回DataTable

目前我使用AutoMapper从数据表的行转换为实体与此Profile

Mapper.CreateMap<DataRow, MyEntity>() 
    .ForMember(d => d.Property, o => o.MapFrom(s => s["property_column"])) 
    // and so on 

这工作完全正常,但我想做拿到实体回数据表行是使用此Profile(不幸的是不工作):

Mapper.CreateMap<MyEntity, DataRow>() 
    .ForMember(d => d["property_column"], o => o.MapFrom(s => s.Property)) 
    // and so on 

如此,因为AutoMapper不能做到这一点我认为我将不得不使用反射 - 但这带来了我的另一个问题。我的实体属性名称与我的数据行的列名称不匹配。所以我不能简单地DataRow[PropertyInfo.Name] = value

我正在考虑使用EntityTypeConfiguration类(对于每个实体)将属性映射到目标列,但这意味着我需要在我的项目中引用实体框架 - 我宁愿避免将其作为它不会被使用。我的第二个(也是首选)想法是为包含目标列名的实体创建自定义属性,并在我的ConvertToDataTable<T>类中反映这些属性以保护数据行。

有没有人有更好的方式来实现这一点,我可能忽略了一些?

回答

1

为了有利于任何人在这个问题上磕磕绊绊,我最终创建了一个自定义的AutoMapper转换器遵循ITypeConverter合同。目前,我正在创建为每个实体类型的自定义转换器,所以我的例子MyEntity这里是我做的:

public class MyEntityToDataTableConvertor : ITypeConvertor<MyEntity, DataTable> 
{ 
    public DataTable Convert(ResolutionContext context) 
    { 
     MyEntity myEntity = (MyEntity)context.SourceValue; 
     DataTable dt = GetDataTableSchema(); 
     DataRow nr = dt.NewRow(); 
     nr["property_column"] = myEntity.Property; 
     // and so on 
     return dt; 
    } 
} 

然后告诉AutoMapper到ConvertUsing为:

Mapper.CreateMap<MyEntity, DataTable>() 
     .ConvertUsing(new MyEntityToDataTableConvertor()); 

我敢肯定我可以使用反射和泛型来重构这一点,但从短期来看,这对我来说非常有用。

+0

对我来说,使用反射的工作速度稍快于简单的硬编码映射,这一点很奇怪。 – 2013-03-12 11:24:22