如何使用使用Model优先的方法的动态连接字符串,但仍然使用在EDMX数据模型? [英] How to use a dynamic connection string using a Model First approach but still use the data model in the EDMX?

查看:1057
本文介绍了如何使用使用Model优先的方法的动态连接字符串,但仍然使用在EDMX数据模型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用EF 5的模型优先方法创建了一个EDMX,即我开始与一个空白的设计师和模型我的实体。现在,我希望能够使用这款机型在EDMX定义,但没有modyfing配置文件提供运行SQL Server的连接字符串。



我知道如何通过一个连接字符串到的DbContext,但问题是定位在装配中映射元数据。



例如,我的EDMX有在App.config此连接字符串

 <添加名称=MesSystemEntities的connectionString =元数据= RES://*/Data.DataContext.EntityFramework.MesSystem.csdl |资源://*/Data.DataContext.EntityFramework.MesSystem.ssdl |高分辨率://*/Data.DataContext.EntityFramework.MesSystem.msl;提供商= System.Data.SqlClient的;提供连接字符串=安培; QUOT;数据源= MYMACHINE;初始目录= MesSystem;集成安全=真; MultipleActiveResultSets = TRUE;应用=&的EntityFramework放大器; QUOT;的providerName =System.Data.EntityClient/> 

这是我缺少的部分是元= RES:// * / Data.DataContext.EntityFramework.MesSystem.csdl |高分辨率://*/Data.DataContext.EntityFramework.MesSystem.ssdl |高分辨率://*/Data.DataContext.EntityFramework.MesSystem.msl;



我希望能够创建一个的DbContext SQL Server连接字符串中的编程方式传递,但增加关于元数据部分。



这是我想通过T4文件...



会产生什么

 公共部分类MesSystemEntities:的DbContext 
{
公共MesSystemEntities()
:基地(NAME = MesSystemEntities)
{
}

公共MesSystemEntities(字符串sqlServerConnectionString)
:基地(GetEfConnectionString(sqlServerConnectionString))
{
}

私人字符串GetEfConnectionString (字符串sqlServerConnectionString)
{
//值由T4代
字符串格式=元数据= RES补充说://*/Data.DataContext.EntityFramework.MesSystem.csdl | RES:// * / Data.DataContext.EntityFramework.MesSystem.ssdl |高分辨率://*/Data.DataContext.EntityFramework.MesSystem.msl ;;提供商= System.Data.SqlClient的;提供连接字符串= \{0} \
返回的String.Format(格式,sqlServerConnectionString);
}

}



我的问题是如何我能得到我需要在T4代文件,而不硬编码为每个EDMX文件





有从装配编程?


解决方案
<加载元数据的更简单的方法p>我有同样的问题,所以不是依靠连接字符串中的所有元数据(我认为是不是一个好主意)我写了从一个标准的连接字符串创建它的方法。 (我也许应该重构它成的DbContext扩展方法,但这应该做的)

 静态内部类ContextConnectionStringBuilder 
{
//修改版本http://stackoverflow.com/a/2294308/209259 $乙$ b公共静态字符串GetEntityConnectionString(字符串的ConnectionString,
型ContextType)
{
字符串结果=的String.Empty;

字符串前缀= ContextType.Namespace
.Replace(ContextType.Assembly.GetName()的名字,);

如果(prefix.Length大于0
和;&放大器;。prefix.StartsWith())
{
PREFIX = prefix.Substring(1, prefix.Length - 1);
}

如果(prefix.Length大于1
和;&安培;!prefix.EndsWith())
{
+前缀=;
}


EntityConnectionStringBuilder csBuilder =
新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
,前缀+ ContextType.Name);

结果= csBuilder.ToString();

返回结果;
}
}



基本用法是一样的东西:

 字符串CONNSTRING = 
ConfigurationMananager.ConnectionStrings [名称]的ConnectionString。

串dbConnectionString = ContextConnectionStringBuilder(CONNSTRING,
typeof运算(MyDbContext));

变种的DbContext =新MyDbContext(dbConnectionString);


I have created an EDMX using EF 5 with the Model First approach, i.e. I started with a blank designer and modeled my entities. Now I want to be able to use this model defined in the EDMX but supply runtime SQL Server connection strings without modyfing the config file.

I know how to pass a connection string to the DbContext but the issue is locating the metadata for the mappings within the assembly.

For example, my EDMX has this connection string in the app.config

<add name="MesSystemEntities" connectionString="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=&quot;data source=MyMachine;initial catalog=MesSystem;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />

The part that I am missing is the "metadata=res://*/Data.DataContext.EntityFramework.MesSystem.csdl|res://*/Data.DataContext.EntityFramework.MesSystem.ssdl|res://*/Data.DataContext.EntityFramework.MesSystem.msl;"

I want to be able to create a DbContext programmatically passing in a SQL Server connection string but "add on" the metadata portion.

This is what I would like to be generated by the T4 file...

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);
    }
...
}

My question is how can I get the metadata I need in the T4 generation file to create the Entity Framework connection without hardcoding it for each EDMX file

OR

is there an easier way to load the metadata from the assembly programmatically?

解决方案

I had the same issue, so instead of relying on all the meta data in the connection string (which I think is not a good idea) I wrote a method to create it from a standard connection string. (I should probably refactor it into an Extension method for DbContext, but this should do)

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;
  }
}

Basic usage is something like:

string connString = 
  ConfigurationMananager.ConnectionStrings["name"].ConnectionString;

string dbConnectionString = ContextConnectionStringBuilder(connString,
                                                           typeof(MyDbContext));

var dbContext = new MyDbContext(dbConnectionString);

这篇关于如何使用使用Model优先的方法的动态连接字符串,但仍然使用在EDMX数据模型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆