简体   繁体   English

DAL中的F#类型提供程序

[英]F# type provider in DAL

I have a solution with 2 projects: 我有2个项目的解决方案:

  1. F# project (for data access + other functions) F#项目(用于数据访问和其他功能)
  2. C# web project (will consume functions from F#) C#Web项目(将使用F#中的函数)

I will need to call SQL Server stored procedures, and am using FSharp.Data.TypeProviders to do the job. 我将需要调用SQL Server存储过程,并正在使用FSharp.Data.TypeProviders来完成这项工作。

type dbSchema = SqlDataConnection< "...", StoredProcedures=true >

let getDbContext connString = 
    match connString with
    | "" -> dbSchema.GetDataContext()
    | _ -> dbSchema.GetDataContext(connString)

Insert: 插入:

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

Or 要么

let insertItem connString item = 
    use dbContext = getDbContext connString
    dbContext.CreateStoredProc(item.Stuff)      
  1. How would I consume this from C# so that I'm not recreating the dbContext every time I do an insert? 我将如何从C#中使用它,以便每次执行插入dbContext都不会重新创建dbContext

I don't want to expose the whole dbContext , just certain stored procedures through the F# DAL. 我不想通过F#DAL公开整个dbContext ,而只公开某些存储过程。

Note: I need to pass in the connection string from web.config 注意:我需要从web.config中传入连接字符串

Similar question here doesn't fully provide my answer: F# Type Provider for SQL in a class 这里的类似问题不能完全提供我的答案: 类中SQL的F#类型提供程序

  1. I am able to set getDbContext to internal or private, but not dbSchema . 我可以将getDbContext设置为内部或私有,但不能将dbSchema Any way to not expose it? 有什么办法不暴露它吗?

If I'm not much mistaken, the context is an instance of DataContext , which isn't thread-safe. 如果我没弄错的话,上下文是DataContext的实例,它不是线程安全的。 None of the data context base classes I'm aware of, are thread-safe, and since you want to use them in a web application, you must, at the very least, create one instance per HTTP request; 我所知的数据上下文基类都不是线程安全的,并且由于要在Web应用程序中使用它们,因此至少必须为每个HTTP请求创建一个实例。 otherwise, the behaviour of your DAL will be defective. 否则,您的DAL行为将是有缺陷的。

On the other hand, within a single request, it may be worthwhile to reuse the same instance. 另一方面, 单个请求中,可能值得重用同一实例。 Therefore, I'd go with this function design: 因此,我将进行以下功能设计:

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

because that would let you create a single dbContext value associated with a single HTTP request, and reuse that for multiple database operations, because you can pass the same dbContext value to more than one function. 因为这样可以使您创建与单个HTTP请求关联的单个dbContext值,并将其重新用于多个数据库操作,因为您可以将同一dbContext值传递给多个函数。

If you want to make all of this accessible from C#, it would be easiest on C# client developers if you wrap all the functionality in classes. 如果要使所有这些都可以从C#访问,那么如果将所有功能都包装在类中,则对C#客户端开发人员来说将是最简单的。 Assuming the above insertItem function, as well as the getDbContext function from the OP, you could define classes like these: 假设上面的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

This will enable a C# client to use a Singleton instance of the ContextFactory class, and for each HTTP request, use its CreateContext method to create an instance of the ContextShim class, and then use the members on the ContextShim instance, such as InsertItem . 这将使C#客户端能够使用ContextFactory类的Singleton实例,并且对于每个HTTP请求,使用其CreateContext方法创建ContextShim类的实例,然后使用ContextShim实例上的成员,例如InsertItem

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM