2012-05-22 31 views
6

基本上,我想为存储过程使用“nice”Dapper语法,而不必手动使用exec MySproc @p1, @p2, @p3, @p4等等,但我需要能够传入强类型对象,并设置各种属性并使此对象用于映射参数。我知道我可以用一个匿名对象来做到这一点,但我想到的场景就像是一个复杂的搜索表单,其中可以搜索多个字段,并且相应的存储过程可以有很多参数(很多都有默认值)。Dapper是否支持使用存储过程强类型化对象?

理想我希望能够做这样的事情:

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似乎只是检查每个属性并分配一个值,假设在sproc中有一个对应的参数可能不存在。

我能做类似这样使用PetaPoco东西(传递一个强类型的对象一个匿名对象),但我要找的东西一点点比PetaPoco是更抽象。我想在Dapper(或者其他的微型ORM?我不能使用NHibernate或者一个重量级的ORM)中做什么,或者我有一种方法可以忽略不计, exec声明与什么可能是十几个参数?

回答

9

如果你想指定PARAMS你需要明确这样做:

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 PARAMS嗅探特效虽然你可能会建立一个帮手,做的是,让你运行: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(); 
+0

这就是我所害怕的,因为使用匿名对象阻止我根据输入动态地构建对象。不过,辅助方法的想法很有趣。 –

+1

@WayneM看到我的编辑... –

+0

现在看起来很有趣。我将不得不玩弄,看看它是如何工作的。非常感谢,山姆! –

2

如果您使用的是SQL Server,请检查Insight.Database。 https://github.com/jonwagner/Insight.Database/wiki它更倾向于存储过程,并使用SqlDeriveParameters来确定对象和存储过程之间的映射。

注意:它目前需要.NET 4.0,但是如果您真的对.NET 3.5版本感兴趣,我可以看到这将是多么困难。