我在类库中使用 EF6(首先是数据库)
当我按照向导添加表时,我选择不在 app.config 中存储连接字符串,而是发送连接字符串。
我以前没有这样做过。通常我选择将连接字符串放在 app.config 文件中。
我现在完全困惑于如何实际调用函数并将连接字符串传递给它。
以下是我希望我的解决方案中的相关代码片段。
在 app.config 中 - EF 自动添加了以下内容:
<connectionStrings>
<add name="cerviondemoEntities" connectionString="metadata=res://*/DatabaseModel.cervionEDM.csdl|res://*/DatabaseModel.cervionEDM.ssdl|res://*/DatabaseModel.cervionEDM.msl;provider=System.Data.SqlClient;provider connection string="data source=DEVBOX;initial catalog=cerviondemo;user id=sa;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
我的自动生成的上下文类如下所示:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace CervionFunctions.DatabaseModel
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class cerviondemoEntities : DbContext
{
public cerviondemoEntities()
: base("name=cerviondemoEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<Customer> Customers { get; set; }
public virtual DbSet<Ticket> Tickets { get; set; }
}
}
最终,我尝试调用以下测试函数:
public static List<Customer> customersToUpdate()
{
cerviondemoEntities db;
using (db = new DatabaseModel.cerviondemoEntities())
{
var result = from customers in db.Customers
select customers;
return result.ToList();
}
}
我无法弄清楚如何将连接字符串发送到该函数。
按照约定,实体框架采用与上下文同名的连接字符串。 例如:
public cerviondemoEntities()
: base("name=cerviondemoEntities")
{
}
DbContext 类有一个采用连接字符串的构造函数。您可以添加另一个采用连接字符串作为参数的构造函数,并将其传递给基本构造函数。
public cerviondemoEntities(string connectionString) : base(connectionString)
{
}
确保创建一个分部类,这样您添加的构造函数就不会被覆盖。
示例连接字符串:
<connectionStrings>
<add name="cerviondemoEntities" connectionString="data source=server\database;initial catalog=catalog;persist security info=True;user id=user;password=password;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
</connectionStrings>
我也遇到了这个问题,并使用了评论中大牛的方法。
或者,您可以将其添加到 .tt 文件中,而不是创建另一个文件并使用“部分” – Daniel K,2016 年 12 月 9 日,19:16
*更新 .Context.tt 文件
只需更换线路...
public <#=code.Escape(container)#>()
: base("name=<#=container.Name#>")
{
具有以下...
public <#=code.Escape(container)#>()
: this("name=<#=container.Name#>")
{
}
public <#=code.Escape(container)#>(String nameOrConnectionString)
: base(nameOrConnectionString)
{
您需要在上下文中引入另一个需要
string connectionString
参数的构造函数,并使其调用 base(string nameOrConnectionString)
:
public cerviondemoEntities(string connectionString) : base(connectionString)
{
}
我使用了这样的连接字符串,实体连接字符串而不是普通的连接字符串
SqlConnectionStringBuilder sqlString = new SqlConnectionStringBuilder()
{
DataSource = "SOURAV-PC", // Server name
InitialCatalog = "efDB", //Database
UserID = "sourav", //Username
Password = "mypassword", //Password
};
//Build an Entity Framework connection string
EntityConnectionStringBuilder entityString = new EntityConnectionStringBuilder()
{
Provider = "System.Data.SqlClient",
Metadata = "res://*/testModel.csdl|res://*/testModel.ssdl|res://*/testModel.msl",
ProviderConnectionString = sqlString.ToString()
};
return entityString.ConnectionString;
}
这是更好的方法。图表或属性的任何更改都会导致 context.cs 被重写。线索是所有文件都被编写为部分类对象。因此,为了不需要在每次更改实体框架时重写上下文,请在 EntityFramework edmx 外部添加一个新的 cs 文件,其中包含一个部分类,其中仅包含之前帖子中讨论的片段。
public partial class cerviondemoEntities
{
public cerviondemoEntities(string connectionString):base(connectionString){}
}
这在最受认可的帖子中进行了讨论,但很容易浏览。如果您更改 EntityFramework 属性,这应该会阻止您的代码不起作用。这对我来说很重要,因为我的应用程序需要连接到远程 SQL 数据库。
上面显示的许多方法(除了 Ian Covill)的问题是,每当数据库中进行一些更改并更新相应的模型时,所有更改都会丢失(例如,另一个带参数的构造函数)。
因此,可以使用另一种方法,与 Ian Covill 提出的非常相似。就我而言,我必须在开发数据库和生产数据库(相同的数据库)之间进行选择。
在 App.config 或 web.config 中
<add name="MyEntities" connectionString="metadata=res://*/Infrastructure.DAL.MyDal.csdl|res://*/Infrastructure.DAL.MyDal.ssdl|res://*/Infrastructure.DAL.MyDal.msl;provider=System.Data.SqlClient;provider connection string="data source=192.168.0.1;initial catalog=MyDBName;user id=user;password="password";MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
<add name="MyEntities_TEST" connectionString="metadata=res://*/Infrastructure.DAL.MyDal.csdl|res://*/Infrastructure.DAL.MyDal.ssdl|res://*/Infrastructure.DAL.MyDal.msl;provider=System.Data.SqlClient;provider connection string="data source=192.168.0.1;initial catalog=My_TEST_DBName;user id=user;password="password";MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
在 *.edmx 之外但在同一文件夹中,创建一个与 EntityFramework 实体名称相同名称的部分类。
public MyEntities(string conStr) : base("name=" + conStr)
{
}
现在,我们可以传递测试或生产数据库连接字符串名称。创建一个分部类(不一定),以便您可以调用此静态方法来根据预处理器指令获取正确数据库的连接字符串。
public partial class TestOrProductionDBSelector
{
public static MyEntities GetTestOrProductionEntity()
{
#if DEBUG
return new MyEntities("MyEntities_TEST");
#else
//ok without param as default is production
return new MyEntities();
#endif
}
}
现在,可以从任何地方调用静态函数 GetTestOrProductionEntity(),它将根据所选的预处理器指令调用适当的连接字符串。
希望这对某人有帮助。这种方法的一大优点是自动生成的 *.Context.cs(在 *.edmx 内)将保持完整,并且消除了其中自定义代码被覆盖的风险。
这是实体框架所需的字符串格式:
metadata=res://*/testModel.csdl|res://*/testModel.ssdl|res://*/testModel.msl;provider=System.Data.SqlClient;provider connection string="Data Source=.;Initial Catalog=Elections;User ID=sa;Password=yourpassword"