2014-12-07 42 views
2

我是如何从Tomas Petricek找到这个fssnip http://www.fssnip.net/hh的。它很好地隐藏了很多非功能代码,同时使用ado.net SqlDataReader。再加上他在存储过程中的另一篇文章http://tomasp.net/blog/dynamic-sql.aspx/,它提供了一种使用原始查询和存储过程查询sql server的好方法。这对于想要使用原始查询但不够幸运的人使用sqlclient类型提供程序非常有用。这个FSharp动态运算符

但是,我无法弄清楚FSharp编译器/ CLR如何处理下列函数的返回类型。

let (?) (reader:SqlDataReader) (name:string) : 'R = 
    let typ = typeof<'R> 
    if typ.IsGenericType && typ.GetGenericTypeDefinition() = typedefof<option<_>> then 
    if reader.[name] = box DBNull.Value then 
     (box null) :?> 'R 
    else typ.GetMethod("Some").Invoke(null, [| reader.[name] |]) :?> 'R 
    else 
    reader.[name] :?> 'R 

当我把一个断点有关此功能,同时施加类似reader?amount,(量为浮子式列)。当我将光标移动到函数签名上时,它显示返回类型'R是执行此函数的单行代码之前的双精度值。编译器/ CLR实际上如何知道数量是一个数字的双倍?功能中似乎没有什么可以帮助推理?

问候

casbby

+1

有这样一个稍长版本,一起在这里解释:http://msdn.microsoft.com/en-us/library/hh304373(v=vs.100).aspx – 2014-12-07 14:15:57

+0

托马斯,感谢您的链接和帖子。有一点让人感到惊讶,围绕着一个不错的F#方式与旧的Sql服务器进行交互的讨论并不多。你的三个职位是我可以在F#中获得的最好的东西给Dapper。不是每个人都有幸能够访问sql2012 +。 – casbby 2014-12-08 00:59:34

+0

@casbby,你为什么提到SQL2012?不要Tomas的教程适用于早期版本? – Mau 2014-12-08 11:48:38

回答

4

所以这里的关键是'R

这可以从使用标准类型推断的编译时推断。

没有必要明确的CLR支持,多带些找出返回值(虽然,你会得到一个异常,如果该类型不匹配)

+2

John,谢谢。当我第三次阅读你的评论时,它突然来到了我的面前。编译器可以计算出该类型的原因是因为我定义了一个记录类型'type figure {amount:double}'。我产生了一个记录{金额=读者?金额}。如果我做了一些愚蠢的事情,像'SELECT firstName [Amount] from peopleTable',编译器会推断它是一个double,执行失败,因为它确实是一个字符串。这实际上是我告诉编译器它是什么类型(没有意识到),而不是它发现它是什么神奇的。 – casbby 2014-12-07 05:53:06