DAL 中的 F# 类型提供程序
本文关键字:程序 类型 中的 DAL | 更新日期: 2023-09-27 18:35:56
我有一个包含 2 个项目的解决方案:
- F# 项目(用于数据访问 + 其他函数)
- 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)
- 我将如何从 C# 中使用它,以便我不会在每次插入时重新创建
dbContext
?
我不想公开整个dbContext
,只是通过 F# DAL 公开某些存储过程。
注意:我需要从 web.config 传入连接字符串
类似的问题在这里并不能完全提供我的答案:类中SQL的F#类型提供程序
- 我可以
getDbContext
设置为内部或私有,但不能dbSchema
。有什么方法可以不暴露它吗?
如果我没记错的话,上下文是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
。