说:
let x = // some operation
type t = SomeTypeProvider<x>
Run Code Online (Sandbox Code Playgroud)
这有效吗?
不.
由于必须在编译时生成类型,因此类型提供程序的参数必须是常量.
换句话说,您标记的代码// some operation可以计算为文字,但不能是runnable函数返回的值:
let arg = "foo"
type t = SomeTypeProvider<arg> // okay
let [<Literal>] arg = """{"name":"foo","value":42}"""
type t = SomeTypeProvider<arg> // okay
let arg = x.ToString()
type t = SomeTypeProvider<arg> // Boom! arg is not a Literal
Run Code Online (Sandbox Code Playgroud)
这取决于您的应用程序,但最常见的情况之一如下:
您有一个与数据库相关的Type Provider,并且需要在运行时从某种配置文件或其他东西中检索连接字符串.因此,开发人员错误地认为他们需要一个可运行的代码来首先检索连接字符串,然后将其传递给Type Provider.
正确的方法如下:
保留两个数据库:一个本地存储在一个常量位置(仅用于模式),另一个用于运行时目的.
将第一个(常量!)传递给类型提供程序.不要担心硬编码的路径; 它仅用于模式检索.
// Use a fixed sample file for schema generation only
type MyCSVData = CsvProvider<"dummy.csv">
// Load the actual data at runtime
let data = MyCSVData.Load(RetrieveFileNameFromConfig())
Run Code Online (Sandbox Code Playgroud)