在为Dapper(Dapper-Dot-Net)使用多图语义时,我们正在寻找以下功能:
SqlMapper.Configure.ForTypeUseFunc<T>(Func<dynamic,T> func);
//example usage
Func<object,Foo> fooFunc = (dynamic o) =>
new Foo{
Name = o.Name,
Status = (StatusTypes)o.StatusID
};
SqlMapper.Configure.ForTypeUseFunc<Foo>(fooFunc);
cnn.Query<Foo,Bar,Foo>...
因此,当Dapper将IDataReader拆分为'Foo'类型时,它会将所有值作为动态传递给fooFunc
,因此会对'Bar'执行相同的操作。传入的“动态”对象将代表拆分列(就像常规多图可能具有重复的列名一样)。
我们怎样才能做到这一点?
背景
我们在一些遗留数据库上广泛使用Dapper,但由于许多旧模式被迫使用动态输出将结果映射到对象(不同的列名,嵌套对象等)
实际情况是,尽管我们正在编写手动映射,但数据库(在我们控制范围之外)与我们的对象之间的任何不一致都在Func中完美而明确地定义。一个包含50个表格(我认为是中等大小)的数据库只需要几个小时的时间来绘制并代表任何开发的一小部分时间......完全值得。
那是好事。
我们正在努力解决的问题是,即使它们在使用时表现良好,我们也很难从我们的func中获得良好的代码重用。理想情况下,我们有一些方法可以使用Dapper的多地图但是分配一个per-type Func:
我查看了ITypeMap和IMemberMap,它们似乎是针对每个字段的自定义映射。我们真的在寻找每种类型的自定义映射(我们将处理分配)。
我很乐意尝试将自己构建成Dapper(并且过去曾做过如此轻微的贡献),但我会喜欢一些指导。
谢谢!
UPDATE
我目前正在尝试Query<dynamic,dynamic,Foo>
但是这没有正确分裂。如果它正确拆分,这对我们有用。我们可以有效地将每个动态插入到我们的func中并返回我们的强类型对象:
Query<dynamic,dynamic,Tuple<Foo,Bar>>((d1,d2)=>Tuple.Create(fooFunc(d1),barFunc(d2)));
Dapper足够偷偷摸摸,允许你拆分多种dynamic
类型。我们可以使用许多幕后实现来实现预期目标。下面是一个。
Query<dynamic,dynamic,Tuple<Foo,Bar>>((d1,d2)=>Tuple.Create(fooFunc(d1),barFunc(d2)));
那很棒。在幕后,您可以将类型/功能存储在任何有意义的内容中(例如,词典。
我们现在要处理的问题是重复的列名称附加了数字(例如AddressID,AddressID1),使'SELECT *'语句不那么有用。