Entity framework 和配置。从静态上下文调用

Entity framework and configuration. Calling from static context

我开始想使用 T4 生成代码。为此,我需要来自数据库的数据。由于项目中的所有数据都已使用 EF 检索,因此我选择使用 EF。 因此,在我的项目中,我创建了一个实用程序 class,其中包含一个 returns 我需要的对象的静态方法。我发现,在 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 持有 class 和 returns 对象的静态方法。现在从项目 B 中的代码我希望调用该静态方法。

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

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

我该如何解决这个问题? 如何配置静态方法以使用 EF 并使其可供调用方参考使用,而不了解 EF?

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

关于 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 方法时,我提供了连接字符串作为参数。 但是如果调用程序集知道 EntityFramework 作为参考,getData 方法仍然只会正确 运行 。

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

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

如果您不想添加整个 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>

参见上面的供应商部分,这告诉 entity framework 在哪里可以找到您正在使用的供应商 (System.Data.SqlClient)