【问题标题】:Entity Framework run-time ConnectionString when using Database First使用 Database First 时的实体框架运行时 ConnectionString
【发布时间】:2021-09-06 16:10:12
【问题描述】:

我正在创建一个使用实体框架的应用程序;具体来说,数据库优先。

当用户登录时,会在运行时创建一个ConnectionString,然后用于应用​​程序中的任何数据处理。

我已经在 Internet 上找到了许多解决方案,建议这样做的方法是为创建的 DbContext 类实现另一个构造函数,该类调用基类 DbContext(string)

public ApplicationDbContext(SqlConnection Connection)
            : base(Connection.ConnectionString)
        {
        }

我在一个单独的文件中创建了这个文件,该文件是生成代码的public partial class,以说明任何进一步生成的代码会覆盖这些文件中已有的内容。

但是,当应用程序运行时,一旦使用此附加构造函数创建了 ApplicationDbContext,就会引发以下异常:

“上下文正在 Code First 模式下使用,代码是从 EDMX 文件生成的,用于 Database First 或 Model First 开发...”

这是有道理的,因为我使用的是数据库优先方法。但是,我在使用 Database First 的地方看到的所有答案都建议这样做。

MSDN 上进一步研究后,我发现实际上还有另一个DbContext 可以使用的构造函数:DbContext(String, DbCompiledModel)。我想知道这是否是我所缺少的,这是我需要的构造函数,因为我会说我使用的是编译模型(......或者我是吗?)。

但是,这是处理它的正确方法还是需要以其他方式处理?

【问题讨论】:

  • 感谢您的反馈;但是我尝试过以这种方式构造 ConnectionString ,但我仍然遇到同样的错误。我检查了 App.config 中 ConnectionString 的格式,以便复制默认使用的 ConnectionString 中的相同参数,但是,当我尝试使用此数据构造 ConnectionString 时,出现错误“不支持关键字”对于“提供者”、“连接字符串”和“提供者连接字符串”。删除这些至少可以构造字符串,但正如我所说,这只会再次导致原始错误。
  • 问题出在传递给构造函数的连接字符串中。

标签: c# entity-framework


【解决方案1】:

首先将构造函数重载添加到您的上下文类以接受string 作为连接字符串:

public TestDBEntities()
    : base("name=TestDBEntities")
{
}
public TestDBEntities(string connectionString)
    : base(connectionString)
{
}

然后使用app.configweb.config 中的连接字符串。您应该将&qout; 替换为",还应包括metadata=...,并且连接应采用以下格式:

var cn = @"metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;" +
         @"provider=System.Data.SqlClient;" +
         @"provider connection string=""" +
         @"data source=(localdb)\v11.0;" +
         @"initial catalog=TestDB;" +
         @"integrated security=True;" +
         @"MultipleActiveResultSets=True;" +
         @"""";
var db = new TestDBEntities(cn);

注意:最好将新的重载放在部分类中。那么每次运行上下文的.tt模板就不会被触动了。

【讨论】:

  • 啊,我明白了,我错过了字符串中的元数据。我确定我已经到了某个地方,因为它现在告诉我“初始化字符串的格式不符合从索引 159 开始的规范。”。在外部查看器中查看字符串后,位置 159 是“提供者连接字符串”的开始。我会进一步调查并尝试找出发生这种情况的原因。
  • 在此处粘贴来自appconfig 的连接字符串。
  • 配置文件的完整行如下。请注意,我用通用术语替换了用户名和密码,只是因为:-) : name="KCAdminContext" connectionString="metadata=res://*/DataEntity.KCAdminEntities.csdl|res://*/DataEntity.KCAdminEntities .ssdl|res://*/DataEntity.KCAdminEntities.msl;provider=System.Data.SqlClient;provider连接字符串=”数据源=ALICE\MSSQL2014;初始目录=KCADMIN_TEST;用户id=USER_NAME;密码=PASSWORD; MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient"
  • 这是您应该使用的确切连接字符串:var cn = @"metadata=res://*/DataEntity.KCAdminEntities.csdl|res://*/DataE‌​ntity.KCAdminEntities.ssdl|res://*/DataEntity.KCAdminEntities.msl;provider=System‌​.Data.SqlClient;provider connection string=""data source=ALICE\MSSQL2014;initial catalog=KCADMIN_TEST;user id=USER_NAME;password=PASSWORD;MultipleActiveResultSets=True;App=EntityFramework‌​""";
  • 注意,你应该为接受string的构造函数创建一个重载。就像我在答案中所做的那样。
【解决方案2】:
    public partial class DataBaseEntities : DbContext
    {
        //public DataBaseEntities()
        //    : base("name=DataBaseName")
        //{
        //}

        public DataBaseEntities()
            : base(ConstValues.ConnectionString)
        {
        }
     }

    public class ConstValues
    {
        public const string ConnectionString = @"metadata=res://*/EntityModel.DataBaseName.csdl|res://*/EntityModelDataBaseName.ssdl|res://*/EntityModel.DataBaseName.msl;provider=System.Data.SqlClient;provider connection string="";data source=.;initial catalog=DataBaseName;user id=mhhfghd;password=12345679;MultipleActiveResultSets=True;App=EntityFramework"";";
    }

您必须将&quot 替换为"

【讨论】:

    猜你喜欢
    • 2017-02-09
    • 1970-01-01
    • 1970-01-01
    • 2015-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-18
    相关资源
    最近更新 更多