Из документации MSDN я понимаю, что, если Run реализован, он будет вызван автоматически в конце вычислительного выражения. Это говорит о том, что:
builder.Run(builder.Delay(fun () -> {| cexpr |}))
будет сгенерировано для вычислительного выражения. Запуск и / или задержка будут опущены, если они не определены в компоновщике рабочих процессов. Я ожидал, что мой ReaderBuilder вернет список объектов MyItem при автоматическом вызове Run. Поэтому я не понимаю, почему я получаю ошибку несоответствия типов. Ошибки сгенерированы оператором return внутриProcessBuilder в конце моего списка кода. Может кто-нибудь объяснить, что я неправильно понимаю в построителях рабочих процессов и что я реализовал неправильно?
Я получаю следующие ошибки:
Тип '' список 'не совместим с типом' ReaderBuilder '
Несоответствие ограничения типа. Тип 'список не совместим с типом ReaderBuilder Тип' 'список' не совместим с типом 'ReaderBuilder'
open System
open System.Data
open System.Data.Common
open System.Configuration
let config = ConfigurationManager.ConnectionStrings.Item("db")
let factory = DbProviderFactories.GetFactory(config.ProviderName)
type Direction =
| In
| Out
| Ref
| Return
type dbType =
| Int32
| String of int
type ReaderBuilder(cmd) =
let mutable items = []
member x.Foo = 2
member x.YieldFrom item =
items <- item::items
item
member x.Run item =
items
type ProcBuilder(procedureName:string) =
let name = procedureName
let mutable parameters = []
let mutable cmd:DbCommand = null
let mutable data = []
member x.Command with get() = cmd
member x.CreateCommand() =
factory.CreateCommand()
member x.AddParameter(p:string*dbType*Direction) =
parameters <- p::parameters
member x.Bind(v,f) =
f v
member x.Reader = ReaderBuilder(cmd)
member x.Return(rBuilder:ReaderBuilder) =
data
let (?<-) (builder:ProcBuilder) (prop:string) (value:'t) =
builder.Command.Parameters.[prop].Value <- value
type MyItem() =
let mutable _a = 0
let mutable _b = String.Empty
let mutable _c = DateTime.Now
member x.a
with get() = _a
and set n = _a <- n
member x.b
with get() = _b
and set n = _b <- n
member x.c
with get() = _c
and set n = _c <- n
let proc name = ProcBuilder(name)
let (%) (builder:ProcBuilder) (p:string*dbType*Direction) =
builder.AddParameter(p)
builder
let (?) (r:DbDataReader) (s:string) = r.GetOrdinal(s)
let foo x y =
let foo = proc "foo" % ("x", Int32, In) % ("y", String(15), In)
foo?x <- x
foo?y <- y
foo {
do! foo?x <- x
do! foo?y <- y
return foo.Reader {
let item = MyItem()
item.a <- r.GetInt32("a")
item.b <- r.GetString("b")
item.c <- r.GetDateTime("c")
yield! item
}
}