Constructing the Connection String for the DataContext Class
-
06-06-2021 - |
質問
I see a couple of DataContext connection string questions. I'm going to try to differentiate this one a bit:
How does one construct a generic connection string to a database, localhost | User-PC\User | Some database... (it is hosted/managed by Microsoft SQL 2008)
I notice that it is IDisposable. So if I have multiple users hitting my site, my code can only access the database one instance at a time, and has to wait until each instance is disposed, in order for the data to be consistent for each user?
Is it possible, by any chance, to somehow enable LINQ in F#-Interactive, and connect to the database from there? I cannot figure out how to enable/load the System.Data dll into fsi. Maybe that is unique to my installation, or it is a common thread? (ie, my installation also does not recognize windows.base.dll--I have to manually get it from programs\reference assemblies).
Anyhow, I've pretty much conclusively discovered that
let x = new System.Data.Linq.DataContext("localhost")
...does not work.
解決
There actually is a somewhat generic way to construct a connection string:
open System.Data.Common
open System.Data.SqlClient
let providerName = "System.Data.SqlClient"
let factory = DbProviderFactories.GetFactory(providerName)
let cnBuilder = factory.CreateConnectionStringBuilder() :?> SqlConnectionStringBuilder
cnBuilder.DataSource <- "localhost"
cnBuilder.InitialCatalog <- "MyDatabase"
cnBuilder.IntegratedSecurity <- true
let connStr = cnBuilder.ConnectionString
他のヒント
1) How does one construct a generic connection string to a database?
There is no generic way to construct a connection string. The best thing to do is to keep the connection string in some configuration file where you can change it depending on your configuration (the name of SQL Server machine, authentication options, whether it is a file-based database or normal). There is a web site with examples for most of the options.
2) I notice that it is IDisposable. So if I have multiple users hitting my site, my code can only access the database one instance at a time [...]?
No, this is not how DataContext
works. The DataContext
does not keep a live connection to the server that would block anybody else from using the SQL server. It keeps some state (i.e. cached entities that were already obtained) and it uses optimistic concurrency to make sure that the state is consistent (you can use transactions to prevent other connections, if that's what you want).
3) Is it possible, by any chance, to somehow enable LINQ in F#-Interactive [...]?
That shouldn't be a problem. You can reference assemblies using #r "foo.dll"
in F# interactive. The typical approach for F# 2.0 is to generate the data context using C# tools and then just reference it (for F# 3.0, things are easier because you can just use type provider).
If you generate LINQ to SQL data context for Northwind
in C#, the F# Interactive use would look like this:
#r @"<whatever_path>\Northwind.dll"
#r "System.Data.Linq.dll"
open Northwind
open Microsoft.FSharp.Linq
let connStr = @"Data Source=.\SQLEXPRESS;AttachDbFilename=<path>\NORTHWND.MDF;" +
@"Integrated Security=True;User Instance=True"
let operation () =
// Using 'use' to make sure it gets disposed at the end
use db = new NorthwindDataContext(connStr)
// do something with the database
My approach was to have 1 connection string and then use that for all of my DataContext connections. So this code builds the EntityConnectionString based on MyConnString:
protected override MyEntities CreateObjectContext()
{
string ConnString =ConfigurationManager.ConnectionStrings["MyConnString"];
string seConn = ConfigurationManager.ConnectionStrings["MyEntities"].ToString();
EntityConnectionStringBuilder ecsb = new EntityConnectionStringBuilder(seConn);
ecsb.ProviderConnectionString = ConnString;
EntityConnection ec = new EntityConnection(ecsb.ToString());
ScheduleEntities ctx = new ScheduleEntities(ec);
return ctx;
}