如何使用Model First方法使用动态连接字符串,但仍然使用EDMX中的数据模型?
我使用EF 5使用Model First方法创建了一个EDMX,即我从一个空白设计师开始并模拟我的实体。 现在,我希望能够使用EDMX中定义的此模型,但提供运行时SQL Server连接字符串,而无需修改配置文件。
我知道如何将连接字符串传递给DbContext但问题是找到程序集中映射的元数据。
例如,我的EDMX在app.config中有这个连接字符串
我缺少的部分是"metadata=res://*/Data.DataContext.EntityFramework.MesSystem.csdl|res://*/Data.DataContext.EntityFramework.MesSystem.ssdl|res://*/Data.DataContext.EntityFramework.MesSystem.msl;"
我希望能够以编程方式创建一个DbContext
传入SQL Server连接字符串,但“添加”元数据部分。
这就是我希望T4文件生成的内容……
public partial class MesSystemEntities : DbContext { public MesSystemEntities() : base("name=MesSystemEntities") { } public MesSystemEntities(string sqlServerConnectionString) : base(GetEfConnectionString(sqlServerConnectionString)) { } private string GetEfConnectionString(string sqlServerConnectionString) { // values added by T4 generation string format = "metadata=res://*/Data.DataContext.EntityFramework.MesSystem.csdl|res://*/Data.DataContext.EntityFramework.MesSystem.ssdl|res://*/Data.DataContext.EntityFramework.MesSystem.msl;;provider=System.Data.SqlClient;provider connection string=\"{0}\""; return String.Format(format, sqlServerConnectionString); } ... }
我的问题是如何在T4生成文件中获取我需要的元数据来创建entity framework连接,而无需为每个EDMX文件对其进行硬编码
要么
是否有一种更简单的方法以编程方式从程序集加载元数据?
我有同样的问题,所以我没有依赖连接字符串中的所有元数据(我认为这不是一个好主意),而是编写了一个方法来从标准连接字符串创建它。 (我应该将它重构为DbContext的Extension方法,但这应该这样做)
internal static class ContextConnectionStringBuilder { // Modified Version of http://stackoverflow.com/a/2294308/209259 public static string GetEntityConnectionString(string ConnectionString, Type ContextType) { string result = string.Empty; string prefix = ContextType.Namespace .Replace(ContextType.Assembly.GetName().Name, ""); if (prefix.Length > 0 && prefix.StartsWith(".")) { prefix = prefix.Substring(1, prefix.Length - 1); } if (prefix.Length > 1 && !prefix.EndsWith(".")) { prefix += "."; } EntityConnectionStringBuilder csBuilder = new EntityConnectionStringBuilder(); csBuilder.Provider = "System.Data.SqlClient"; csBuilder.ProviderConnectionString = ConnectionString.ToString(); csBuilder.Metadata = string.Format("res://{0}/{1}.csdl|" + "res://{0}/{1}.ssdl|" + "res://{0}/{1}.msl" , ContextType.Assembly.FullName , prefix + ContextType.Name); result = csBuilder.ToString(); return result; } }
基本用法如下:
string connString = ConfigurationMananager.ConnectionStrings["name"].ConnectionString; string dbConnectionString = ContextConnectionStringBuilder(connString, typeof(MyDbContext)); var dbContext = new MyDbContext(dbConnectionString);
- Howto:Parallel.Foreach在每个进程运行一个新进程(但一次只有一个进程)后执行许多进程?
- 带集合的模型 – Html.ListBoxFor不设置所选项
- 带有RTZ2时区的.Net Framework问题
- 自定义StronglyTyped BindingSource项目添加
- 使用gcAllowVeryLargeObjects的OutOfMemoryException
- Task.WaitAll不等待任务完成
- 启用本机代码调试时,AccessViolationException消失
- 为什么这个代码在通过TPL / Tasks执行时会失败?
- 如何使用CSharpCodeProvider定位.net 4.5?