Iva*_*ono 75 c# entity-framework connection-string asp.net-web-api
我有一个Web API项目,它引用了我的模型和DAL程序集.向用户呈现登录屏幕,他可以在其中选择不同的数据库.
我按如下方式构建连接字符串:
public void Connect(Database database)
{
//Build an SQL connection string
SqlConnectionStringBuilder sqlString = new SqlConnectionStringBuilder()
{
DataSource = database.Server,
InitialCatalog = database.Catalog,
UserID = database.Username,
Password = database.Password,
};
//Build an entity framework connection string
EntityConnectionStringBuilder entityString = new EntityConnectionStringBuilder()
{
Provider = database.Provider,
Metadata = Settings.Default.Metadata,
ProviderConnectionString = sqlString.ToString()
};
}
Run Code Online (Sandbox Code Playgroud)
首先,我如何实际更改数据上下文的连接?
其次,由于这是一个Web API项目,连接字符串(在每个登录时设置)在整个用户的交互中是持久的还是应该每次都传递到我的数据上下文?
jim*_*lan 103
这个答案有点晚了,但我认为用一个简洁的小扩展方法有可能做到这一点.我们可以利用EF约定优于配置以及一些小框架调用.
无论如何,注释的代码和示例用法:
扩展方法类:
public static class ConnectionTools
{
// all params are optional
public static void ChangeDatabase(
this DbContext source,
string initialCatalog = "",
string dataSource = "",
string userId = "",
string password = "",
bool integratedSecuity = true,
string configConnectionStringName = "")
/* this would be used if the
* connectionString name varied from
* the base EF class name */
{
try
{
// use the const name if it's not null, otherwise
// using the convention of connection string = EF contextname
// grab the type name and we're done
var configNameEf = string.IsNullOrEmpty(configConnectionStringName)
? source.GetType().Name
: configConnectionStringName;
// add a reference to System.Configuration
var entityCnxStringBuilder = new EntityConnectionStringBuilder
(System.Configuration.ConfigurationManager
.ConnectionStrings[configNameEf].ConnectionString);
// init the sqlbuilder with the full EF connectionstring cargo
var sqlCnxStringBuilder = new SqlConnectionStringBuilder
(entityCnxStringBuilder.ProviderConnectionString);
// only populate parameters with values if added
if (!string.IsNullOrEmpty(initialCatalog))
sqlCnxStringBuilder.InitialCatalog = initialCatalog;
if (!string.IsNullOrEmpty(dataSource))
sqlCnxStringBuilder.DataSource = dataSource;
if (!string.IsNullOrEmpty(userId))
sqlCnxStringBuilder.UserID = userId;
if (!string.IsNullOrEmpty(password))
sqlCnxStringBuilder.Password = password;
// set the integrated security status
sqlCnxStringBuilder.IntegratedSecurity = integratedSecuity;
// now flip the properties that were changed
source.Database.Connection.ConnectionString
= sqlCnxStringBuilder.ConnectionString;
}
catch (Exception ex)
{
// set log item if required
}
}
}
Run Code Online (Sandbox Code Playgroud)
基本用法:
// assumes a connectionString name in .config of MyDbEntities
var selectedDb = new MyDbEntities();
// so only reference the changed properties
// using the object parameters by name
selectedDb.ChangeDatabase
(
initialCatalog: "name-of-another-initialcatalog",
userId: "jackthelady",
password: "nomoresecrets",
dataSource: @".\sqlexpress" // could be ip address 120.273.435.167 etc
);
Run Code Online (Sandbox Code Playgroud)
我知道你已经有了基本功能,但是认为这会增加一点点多样性.
Moh*_*oho 57
DbContext
有一个构造函数重载,它接受连接字符串的名称或连接字符串本身.实现您自己的版本并将其传递给基础构造函数:
public class MyDbContext : DbContext
{
public MyDbContext( string nameOrConnectionString )
: base( nameOrConnectionString )
{
}
}
Run Code Online (Sandbox Code Playgroud)
然后,只需在实例化时传递已配置连接字符串的名称或连接字符串本身 DbContext
var context = new MyDbContext( "..." );
Run Code Online (Sandbox Code Playgroud)
A.I*_*Ima 12
Jim Tollan的回答非常好,但我得到了错误:关键字不支持'数据源'.为了解决这个问题,我不得不改变他的代码的这一部分:
// add a reference to System.Configuration
var entityCnxStringBuilder = new EntityConnectionStringBuilder
(System.Configuration.ConfigurationManager
.ConnectionStrings[configNameEf].ConnectionString);
Run Code Online (Sandbox Code Playgroud)
对此:
// add a reference to System.Configuration
var entityCnxStringBuilder = new EntityConnectionStringBuilder
{
ProviderConnectionString = new SqlConnectionStringBuilder(System.Configuration.ConfigurationManager
.ConnectionStrings[configNameEf].ConnectionString).ConnectionString
};
Run Code Online (Sandbox Code Playgroud)
我真的很抱歉.我知道我不应该使用答案回答其他答案,但我的答案太长了评论:(
小智 6
创建的类是'部分'!
public partial class Database1Entities1 : DbContext
{
public Database1Entities1()
: base("name=Database1Entities1")
{
}
Run Code Online (Sandbox Code Playgroud)
......你这样称呼它:
using (var ctx = new Database1Entities1())
{
#if DEBUG
ctx.Database.Log = Console.Write;
#endif
Run Code Online (Sandbox Code Playgroud)
所以,你只需要为原始自动生成的类(具有相同的类名!)创建一个部分自己的类文件,并添加一个带有连接字符串参数的新构造函数,就像之前Moho的回答一样.
在它之后你可以使用参数化构造函数对原始.:-)
例:
using (var ctx = new Database1Entities1(myOwnConnectionString))
{
#if DEBUG
ctx.Database.Log = Console.Write;
#endif
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
111304 次 |
最近记录: |