DAL 中的 F# 类型提供程序

本文关键字:程序 类型 中的 DAL | 更新日期: 2023-09-27 18:35:56

我有一个包含 2 个项目的解决方案:

  1. F# 项目(用于数据访问 + 其他函数)
  2. C# Web 项目(将使用 F# 中的函数)

我需要调用SQL Server存储过程,并且正在使用FSharp.Data.TypeProviders来完成这项工作。

type dbSchema = SqlDataConnection< "...", StoredProcedures=true >
let getDbContext connString = 
    match connString with
    | "" -> dbSchema.GetDataContext()
    | _ -> dbSchema.GetDataContext(connString)

插入:

let insertItem dbContext item = 
    dbContext.CreateStoredProc(item.Stuff) 

let insertItem connString item = 
    use dbContext = getDbContext connString
    dbContext.CreateStoredProc(item.Stuff)      
  1. 我将如何从 C# 中使用它,以便我不会在每次插入时重新创建dbContext

我不想公开整个dbContext,只是通过 F# DAL 公开某些存储过程。

注意:我需要从 web.config 传入连接字符串

类似的问题在这里并不能完全提供我的答案:类中SQL的F#类型提供程序

  1. 我可以getDbContext设置为内部或私有,但不能dbSchema。有什么方法可以不暴露它吗?

DAL 中的 F# 类型提供程序

如果我没记错的话,上下文是DataContext的一个实例,它不是线程安全的。据我所知,没有一个数据上下文基类是线程安全的,并且由于您想在 Web 应用程序中使用它们,因此您必须至少为每个 HTTP 请求创建一个实例;否则,DAL 的行为将有缺陷。

另一方面,在单个请求,重用同一实例可能是值得的。因此,我会采用这个函数设计:

let insertItem dbContext item = 
    dbContext.CreateStoredProc(item.Stuff)

因为这将允许您创建与单个 HTTP 请求关联的单个 dbContext 值,并将其重用于多个数据库操作,因为您可以将相同的 dbContext 值传递给多个函数。

如果要使所有这些功能都可以从 C# 访问,则在 C# 客户端开发人员中,将所有功能包装在类中将是最简单的方法。假设上述insertItem函数以及 OP 中的 getDbContext 函数,您可以定义如下类:

type ContextShim internal(ctx) =
    member x.InsertItem(item : Item) =
        insertItem ctx item
type ContextFactory() =
    member x.CreateContext connectionString =
        let ctx = getDbContext connectionString
        ContextShim ctx

这将使 C# 客户端能够使用 ContextFactory 类的单一实例,并且对于每个 HTTP 请求,使用其 CreateContext 方法创建ContextShim类的实例,然后使用ContextShim实例上的成员,例如 InsertItem