我有一个包含2个项目的解决方案:
我需要调用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)
dbContext
?我不希望通过F#DAL暴露整个dbContext
,只暴露某些存储过程。
注意:我需要从web.config传递连接字符串
此处的类似问题并未完全提供我的答案:F# Type Provider for SQL in a class
getDbContext
设置为内部或私有,但不能dbSchema
。有什么办法不暴露它吗?答案 0 :(得分:3)
如果我没有太多错误,那么上下文就是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
类的Singleton实例,并且对于每个HTTP请求,使用其CreateContext
方法创建ContextShim
类的实例,然后使用ContextShim
实例上的成员,例如InsertItem
。