Dapper是否支持带有存储过程的强类型对象?

7
基本上,我想使用“好看”的Dapper语法来调用存储过程,而不需要手动使用exec MySproc @p1, @p2, @p3, @p4等方式,但是我需要能够传递一个具有各种属性设置的强类型对象,并将该对象用于映射参数。我知道可以使用匿名对象实现此目的,但是我考虑的情况可能是一个复杂的搜索表单,其中可以搜索多个字段,并且相应的存储过程可能具有许多参数(其中许多带有默认值)。
理想情况下,我希望能够像这样做:
var cust = new Customer();
cust.FirstName = ...
cust.LastName = ...

// using .NET 3.5 so need to use ugly syntax :(
var result = connection.Query<Customer>("MySproc", cust, null, false, null, CommandType.StoredProcedure).Single();

然而,这种方法行不通并引发错误,因为我的客户对象可能有十几个或更多属性,而在这种情况下我只需要查找其中两个;Dapper似乎只是检查每个属性并分配值,假设存储过程中存在相应的参数,但实际上可能并不存在。
使用PetaPoco可以进行类似的操作(传递强类型对象或匿名对象),但我正在寻找比PetaPoco更加抽象化的东西。
是否有可能在Dapper(或其他微型ORM)中实现我想要的功能?我不能使用NHibernate或重量级ORM,除了编写一个可能有十几个参数的exec语句,我是否忽略了其他方法来实现相同的功能?
2个回答

10

如果您想指定参数,您需要明确地这样做:

var result = connection.Query<Customer>("MySproc", 
     new {cust.Id, cust.Name}, // specify the params you want to give it.  
     null, 
     false, 
     null, 
     CommandType.StoredProcedure).Single();

我们不会为存储过程执行 sp_help 参数嗅探,但是您可以潜在地构建一个帮助程序来执行这个任务,并允许您运行:cust.ToProcParams('MySproc')

或者,如果您想动态构建此参数,可以使用。

var dp = new DynamicParameters(); 
dp.Add("Id", cust.Id);
dp.Add("Name", cust.Name);
var result = connection.Query<Customer>("MySproc", 
         dp,
         null, 
         false, 
         null, 
         CommandType.StoredProcedure).Single();

这正是我担心的,因为使用匿名对象会妨碍我根据输入动态构建对象。不过,辅助方法的想法很有趣。 - Wayne Molina
现在看起来很有趣。我得试着玩一下,看看它是如何工作的。非常感谢,Sam! - Wayne Molina

2
如果您使用的是SQL Server,请查看Insight.Database。它更加注重存储过程,并使用SqlDeriveParameters来确定对象和存储过程之间的映射关系。请访问https://github.com/jonwagner/Insight.Database/wiki。注意:目前需要.NET 4.0,但如果您真的对.NET 3.5版本感兴趣,我可以看看这有多难。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接