实体框架和配置。从静态上下文调用

时间:2016-10-26 07:35:16

标签: c# entity-framework configuration t4

我开始想用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 使用返回对象的静态方法保存类。现在,从Project B 中的代码,我希望调用该静态方法。

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

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

我该如何解决这个问题? 如何配置静态方法以使用EF并使其可用作对主叫方的参考,而不知道EF?

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

2 个答案:

答案 0 :(得分:1)

如果您不想添加整个EF包,那么只需在Project 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>

请参阅上面的provider部分,这告诉实体框架在哪里找到您正在使用的提供程序(System.Data.SqlClient)

答案 1 :(得分:0)

关于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方法时,我提供了connectionstring作为参数。 但是,如果调用程序集知道EntityFramework作为引用,则getData方法仍然只能正常运行。

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

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