Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net core F#:我是否可以通过引用另一个程序集来扩展具有附加模块的模块?_.net Core_F# - Fatal编程技术网

.net core F#:我是否可以通过引用另一个程序集来扩展具有附加模块的模块?

.net core F#:我是否可以通过引用另一个程序集来扩展具有附加模块的模块?,.net-core,f#,.net Core,F#,我正在开发一个小型的F#ADO.NET“包装器”(是的,另外还有一个,以及GitHub上的许多其他包装器),我正在考虑扩展对不同ADO.NET提供程序的支持 基本上,我有一个核心项目(即Michelle.Sql.core),包含核心类型和函数,有点类似于Dapper: 类型IDbValue DbParameter>= 抽象TopParameter:string->'DbParameter 类型commanddefinitiondbconnection 和'DbParameter:>DbParam

我正在开发一个小型的F#ADO.NET“包装器”(是的,另外还有一个,以及GitHub上的许多其他包装器),我正在考虑扩展对不同ADO.NET提供程序的支持

基本上,我有一个核心项目(即Michelle.Sql.core),包含核心类型和函数,有点类似于Dapper:

类型IDbValue DbParameter>=
抽象TopParameter:string->'DbParameter
类型commanddefinitiondbconnection
和'DbParameter:>DbParameter
和'DbType:>IDbValue>=
{语句:语句
参数:(string*'DbType)列表
CancellationToken:CancellationToken
超时:时间跨度
存储过程:bool
准备:布尔
事务:DbTransaction选项}
首先,您可能会认为“哇,有很多泛型修饰了您的类型定义!”

好的,首先,我试图绕过一些限制,最值得注意的是这一点:(以及它的优点),我认为我可以通过创建一个C#项目并在该项目中强制约束来规避这个问题,但它不起作用

我之所以需要很多通用约束,是因为我需要一个强类型连接,它可以通过设置该记录不同字段值的调用“流动”,例如:

let playWithQlite()=
使用连接=新建SQLiteConnection()
Sql.statement“插入到表(aColumn)值(@aNumber);”
|>Sql.prepare-true
|>Sql.timeout(TimeSpan.FromMinutes(1.))
|>Sql.parameters[(“aNumber”,SqliteDbValue.Integer 42L)]
|>Sql.ExecuteOnQuery连接
仅供参考,
SqliteDbValue
在不同的程序集中定义
Michelle.Sql.Sqlite

// https://www.sqlite.org/datatype3.html
type SqliteDbValue =
    | Null
    | Integer of int64
    | Real of double
    | Text of string
    | Blob of byte array
    interface IDbValue<SQLiteConnection, SQLiteParameter> with
        member this.ToParameter(name) =
            let parameter = SQLiteParameter()
            // Not so secret impl. goes here...
            parameter
因此,您可以看到,在上面的
executeScalar
函数中,由于一种类型必须显式,这意味着在调用该函数时,其他所有通用参数都必须显式,这意味着最终用户现在需要输入4个通用参数:

// [...] setting up the CommandDefinition...
|> Sql.executeScalar<int64, SQLiteConnection, SQLiteParameter, SqliteDbValue> connection
但战略的问题在于,它本质上可以归结为跟踪:

因此,下面的代码不起作用:

打开Michelle.Sql.Sqlite
打开Michelle.Sql.Core
//[…]正在设置命令定义。。。连接是SQLiteConnection的实例
|>Sql.executeScalar连接
而那一个呢,

打开Michelle.Sql.Core
打开Michelle.Sql.Sqlite
//[…]正在设置命令定义。。。连接是SQLiteConnection的实例
|>Sql.executeScalar连接
我希望能有一个解决方案,尽管我对静态类感兴趣,但不能跨多个程序集定义分部类

我知道F#module函数不可能实现重载,从开发人员的经验来看,隐藏看起来不是一个可行的解决方案


那么,有什么解决办法吗?(撇开创建另一个具有不同名称的函数或具有不同名称的不同模块不谈)

Koenig Lear建议:


这不是一个真正的答案,但为什么不将原始模块重命名为CoreSQL,然后可以为每种驱动程序类型创建模块,例如
Sql.executeScalar
连接
命令定义
let ExecuteOnQuery连接(commandDefinition:SqliteCommandDefinition)=
Sql.ExecuteOnQuery连接命令定义

Koenig Lear建议:


这不是一个真正的答案,但为什么不将原始模块重命名为CoreSQL,然后可以为每种驱动程序类型创建模块,例如
Sql.executeScalar
连接
命令定义
let ExecuteOnQuery连接(commandDefinition:SqliteCommandDefinition)=
Sql.ExecuteOnQuery连接命令定义

这不是真正的答案,但为什么不将原始模块重命名为CoreSQL,然后您可以为每种驱动程序类型创建模块,例如Sql。execluteScalar@KoenigLear这就是我最后所做的。这不是一个真正的答案,但为什么不将原始模块重命名为CoreSQL,然后您可以为每种驱动程序类型创建模块,例如。Sql。execluteScalar@KoenigLear这就是我最后做的。