使用表达式树映射?有可能实现这个吗?

时间:2012-06-01 21:10:24

标签: c# .net-4.0

public static MapFrom Map(this IDataReader idr, params string[] columns)
{
     return new MapFrom { Columns = columns };
}
public static IEnumerable<TEntity> To<TEntity>(this MapFrom from, Func<TEntity, object> map)
{
     // logic here.
}    

public IEnumerable<FooEntity> Execute()
{
    using (DbCommand cmd = db.GetStoredProcCommand("GetListOfFoo"))
    {
        using (IDataReader idr = db.ExecuteReader(cmd))
        {
            return idr.Map("FooID", "FooOfPooAmount", "AnotherFooColumn", "BarID")
              .To<FooEntity>(x => new object[]{
                          x.FooID, x.FooOfPooAmount, x.AnotherFoo, x.BarID
            });
         }
     }
}

我希望使用数据阅读器并创建一个易于使用且性能也很好的简单映射器。我没有太多使用表达树,但我觉得可能需要它们。我想要做的是检查x的关系到它的数组(lambda表达式),然后使用这种关系自动映射值并创建一个新的Foo Entities列表。

MapFrom只是一个容纳信息并允许流畅扩展方法的容器。

这些杂技的关键是要有一种简单的方法来指定关系。我意识到我可以轻松地以不同的形式做一些事情,但我希望能够“流利地”列出列[1](如在键入列名作为字符串后跟逗号然后下一列名称)然后列出对象按顺序排列属性并从中推断出映射。可以实现上面的 To 方法吗?表达树是否适用于此?我想我可以很容易地从FooEntity属性类型推断数据读取器字段的类型转换。

[1]在这种情况下,我并不像“Fluent API”那样流利。

1 个答案:

答案 0 :(得分:2)

我在这里写了你的 MapFrom 类,而不是你必须编写代码来将值从列复制到FooEntity实例的属性,并使用yield return语句返回一个您的实体的集合,因此在 MapFrom 类中添加另一种方法:

public class MapFrom
{
    private readonly IDictionary<string, string> columnMapDictionary =
        new Dictionary<string, string>();

    public MapFrom(string[] columns)
    {
        foreach (var column in columns)
        {
            columnMapDictionary.Add(column, null);
        }
    }

    public void To<T>(params Expression<Func<T, object>>[] properties)
    {
        var index = 0;
        foreach (var columnMap in columnMapDictionary.ToDictionary(k => k.Key))
        {
            var member = (properties[index++].Body as MemberExpression);
            var propertyName = member.Member.Name;
            columnMapDictionary[columnMap.Key] = propertyName;  
        }
    }
}

将其用作:

var mapper = new MapFrom("Name", "Surname");
mapper.To<FooEntity>(p => p.FirstName, p => p.LastName);