我有一个包含 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 传入连接字符串
这里的类似问题没有完全提供我的答案:F# Type Provider for SQL in a class
- 我可以将
getDbContext
设置为内部或私有(private),但不能将dbSchema
设置为内部或私有(private)。有什么办法不暴露吗?
最佳答案
如果我没记错的话,上下文是 DataContext 的一个实例,这不是线程安全的。我所知道的数据上下文基类都不是线程安全的,并且由于您想在 Web 应用程序中使用它们,因此您必须至少为每个 HTTP 请求创建一个实例;否则,您的 DAL 的行为将会有缺陷。
另一方面,在单个请求中,重用同一实例可能是值得的。因此,我会采用这样的功能设计:
let insertItem dbContext item =
dbContext.CreateStoredProc(item.Stuff)
因为这会让你创建一个dbContext
与单个 HTTP 请求关联的值,并将其重用于多个数据库操作,因为您可以传递相同的 dbContext
对多个函数的值(value)。
如果您希望通过 C# 访问所有这些内容,那么将所有功能包装在类中对于 C# 客户端开发人员来说是最简单的。假设上述insertItem
函数,以及 getDbContext
OP 中的函数,您可以定义如下类:
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
的 Singleton 实例。类,并且对于每个 HTTP 请求,使用其 CreateContext
方法来创建 ContextShim
的实例类,然后使用 ContextShim
上的成员实例,例如InsertItem
.
关于c# - DAL 中的 F# 类型提供程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27751823/