【问题标题】:Entity framework and configuration. Calling from static context实体框架和配置。从静态上下文调用
【发布时间】:2016-10-26 07:35:15
【问题描述】:

我开始想使用 T4 生成代码。为此,我需要来自数据库的数据。由于项目中的所有数据都已使用 EF 检索,因此我选择使用 EF。 因此,在我的项目中,我创建了一个实用程序类,其中包含一个返回我需要的对象的静态方法。我发现,在 T4 自定义工具的上下文中运行我无法从配置中读取。所以我手动设置了我的上下文的连接字符串,它起作用了!

    private static string GetConnectionString()
    {
        //How to read from the web.config when running a T4 template ?
        //ConnectionStringSettings settings = ConfigurationManager.ConnectionStrings["XXXXXXX"];
        //var connectionString = settings.ConnectionString;
        var connectionString = @"Data Source=XXXXXX;Initial Catalog=XXXXXX;Integrated Security=SSPI;MultipleActiveResultSets=true;";
        return connectionString;
    }

后来我在我的解决方案中添加了一个项目。项目 A 包含具有返回对象的静态方法的类。现在从项目 B 的代码中,我希望调用该静态方法。

运行该代码时,我收到一个错误:“没有为 ADO.NET 提供程序找到具有不变名称“System.Data.SqlClient”的实体框架提供程序。确保提供程序已在“entityFramework”部分中注册应用程序配置文件的名称。有关详细信息,请参阅http://go.microsoft.com/fwlink/?LinkId=260882"

当我为项目 B 安装 nuget 包 EF 时,代码按预期运行。 但这超出了在项目 A 中创建实用程序类的全部目的。 调用方应该只接收对象而不管它自己的上下文。

我该如何解决这个问题? 在不知道 EF 的情况下,如何配置静态方法以使用 EF 并使其可用作调用方的参考?

我认为答案可能类似于重写 EF 行为以从实用程序类中提供的静态上下文中读取,而不是从当前运行时提供的配置中读取。但是你怎么能这样做呢?

【问题讨论】:

  • 调用项目(即实际创建 DbContext 的项目)需要引用,因为在此上下文中读取应用程序配置。不知道EF在这方面是否支持拆分配置功能。

标签: c# entity-framework configuration t4


【解决方案1】:

如果您不想添加整个 EF 包,则只需在项目 B 中添加对 EntityFramework.SqlServer.dll 的引用。

即使项目 B 引用了项目 A,它也不会复制此文件,因为它在 EF 部分的配置文件中被引用。

 <entityFramework>
     <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory,    EntityFramework">
        <parameters>
           <parameter value="mssqllocaldb" />
        </parameters>
     </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
     </providers>
  </entityFramework>

参见上面的提供者部分,这告诉实体框架在哪里可以找到你正在使用的提供者(System.Data.SqlClient)

【讨论】:

  • 顺便说一句,实际问题已经解决很久了,通过选择一种完全不同的方法,它也满足了所需的用户功能。
  • 那么完整的解决方案是什么? EF 动态加载您设置的提供程序,但如果您在链接链中有多个项目并且不添加对 SQLClient 库的引用,则不会将其复制到输出文件夹。我猜你也可以使用构建后任务并以这种方式复制 SQLClient 库,如果你真的不想获取额外的引用,但这似乎有点矫枉过正,而且其他开发人员更难知道正在发生这种情况
【解决方案2】:

关于 T4 模板的第一部分,我可以通过手动设置连接字符串来解决:

    /// <summary>
    /// When calling from a T4 template, it seems you cannot use the ConfigurationManager.
    /// </summary>
    /// <returns></returns>
    private static string GetConnectionString()
    {
        var connectionString = string.Empty;

        if (ConfigurationManager.ConnectionStrings["DBContext"] != null)
        {
            connectionString = ConfigurationManager.ConnectionStrings["DBContext"].ConnectionString;
        }
        else if (System.Reflection.Assembly.GetExecutingAssembly().GetName().Name == "MyApplication")
        {
            ExeConfigurationFileMap configToUse = null;
            var possibleConfig = System.Reflection.Assembly.GetExecutingAssembly().Location + ".config";
            if (File.Exists(possibleConfig))
            {
                configToUse = new ExeConfigurationFileMap();
                configToUse.ExeConfigFilename = possibleConfig;
                var config = ConfigurationManager.OpenMappedExeConfiguration(configToUse, ConfigurationUserLevel.None);
                connectionString = config.ConnectionStrings.ConnectionStrings["DBContext"].ConnectionString;
            }
        }            
        return connectionString;
    }

我使用该连接字符串创建了一个 System.Data.Entity.DbContext 并将其提供给 GenericUnitOfWork。 现在 T4 可以正常运行我的 getData 方法了。

当我从另一个项目调用 getData 方法时,我提供了连接字符串作为参数。 但是 getData 方法仍然只有在调用程序集知道 EntityFramework 作为参考时才能正常运行。

所以我在另一个项目中添加了对 EF 的引用。它有效。

但我还是不满意:如何配置我的getData方法调用程序集不需要引用EF?我的意思是应该可以吧?

【讨论】:

  • 即使这样也行不通!调试模板时可能的配置文件:C:\Workspaces\My Application\bin\MyApplication.dll.config。但是 C:\Users\myuser\AppData\Local\assembly\dl3\LB1NKXJR.QT0\YX0JMA7K.4V3\f116a810\623287ac_972fd201\MyApplication.dll.config 运行模板时。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-28
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
  • 2011-07-06
相关资源
最近更新 更多