SQL类型提供程序与ROP - F#

时间:2015-02-03 16:17:22

标签: f# type-providers f#-data

我试图使用铁路导向编程原则http://fsharpforfunandprofit.com/rop/和此http://indiedevspot.azurewebsites.net/2015/01/20/two-track-coding-rop-for-dummies-part-2/作为参考

我已经成功地为大多数代码库实现了这个,除了现在我们将项目放入SQL并希望使用ROP来验证这些类型。典型的模式是

图1:

let createSomething a b c = {A = a; B = b; C = c}
let createValidSomething so = 
    createSomething
    <!> validateFunction1 so.param1
    <*> validateFunction2 so.param2
    <*> ...so forth and so on

您会注意到createSomething是一个返回记录类型实例的函数a - &gt; b - &gt; c - &gt;一个&#39; - &GT; B&#39; - &GT; C&#39; SQL类型提供程序返回可变类型(非记录)。让我们看看我尝试构建类似的createSomething函数

图2:

    let createSQS(a, b, c, d, e, f, g) =
    let sqs = context.``[dbo].[Something]``.Create(a, b, c, d, e, f, g)
    sqs

此时,我们知道这已经不起作用,我们有a-&gt; b-&gt; c-&gt; d-&gt; e-&gt; f-&gt; g-&gt; context。{{1 }}。实体

我知道我可以拥有中间记录类型并遵循ROP主体,匹配成功/失败,然后从已经验证的对象创建我的对象。但这看起来不是太多步骤吗?

有人知道这个好模式吗?理想情况下,我们可以使用类似于图1的函数来生成与类型提供程序兼容的记录类型。

我愿意尝试并在Skype上闲逛:)。

2 个答案:

答案 0 :(得分:1)

你的函数createSQS不应该更好:

let createSQS a b c d e f g =
    context.``[dbo].[Something]``.Create(a, b, c, d, e, f, g)

这个将具有a->b->c->d->e->f->g->context.[dbo].[Something].Entity

所需的签名

答案 1 :(得分:1)

所以我们在开发会议上得到了答案,并决定我们实际上想要在自己的功能中执行每个部分。对于内在的束缚,我们发明了自己的运算符;类似于plus(&amp;&amp;&amp;)(我将在我的网站上发布博客www.indiedevspot.com),在顶层我们使用普通绑定运行。

我们的顶级代码如下所示:

[<HttpPost>]
x.member Add(sa:Something) =
           sa|>ValidateSomething
           >>= converttoSSA
           >>= persistSSA

由于验证,转换和持久性的独立可测试性,我们决定将问题分开。该理论认为,功能组合如果由保证有效的功能组成,本身就可以保证工作(或者有更好的机会)。

如果我们采用所提出的方法(我们还没有解决),我们会混淆创建,验证和转换的问题。这也最终会创建一个不必要的额外记录类型。