如何首先覆盖 EF 代码中的 "invisible" 连接字符串?
How to override an "invisible" connection string in EF code first?
我首先通过代码使用 EF 6.1.2 编写了我的应用程序。输入命令 "Update Database" 后,数据库已在我的 Microsoft SQL Server 2017 中创建。到目前为止一切顺利。但是,我从未在我的 app.config(来自 class 库)中看到我的数据库的连接字符串。它只是不存在,但是,令我惊讶的是它有效。它完美地连接到我的本地服务器。
现在,我已经将我的数据库移动到云端,因此我有一个连接字符串。我已将我的连接字符串复制粘贴到应用程序配置中,但它仍然指向初始服务器。
我的 app.config 看起来像这样:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<!--For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468-->
</configSections>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
I tried putting the connection string but it takes no effect. It still points to the local server. I have even deleted everything, and pasted my connection string but no success.
Any ideas of how to add my connection string so that it will point to the database from the cloud?
**UPDATE**:
The web.config as Roman requested. I have put the connection string there but it makes no difference (yes I am am aware of the 'X'-s, I don't wanna share the database :-) ):
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="freeaspconnection" connectionString="Server=XXXX;Database=XXXXXX;uid=liviusosu;pwd=;" providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="NumberOfUserTasksPerPage" value="7" />
<add key="NumberOfArticlesPerPage" value="10" />
<add key="NumberOfCoursesPerPage" value="10" />
<add key="NumberOfJobAnnouncementsPerPage" value="30" />
<add key="NumberOfInterviewQuestionsPerPage" value="30" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" maxRequestLength="1048576" />
<authentication mode="Forms">
<forms loginUrl="User/LogIn" timeout="300" />
</authentication>
</system.web>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701" />
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+" />
</compilers>
</system.codedom>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
这里是 DBContext
public class CareerTrackContext : DbContext
{
public CareerTrackContext()
: base("CareerTrack")
{
}
public DbSet<User> Users { get; set; }
public DbSet<Article> Articles { get; set; }
public DbSet<UserTask> UserTasks { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<Company> Companies { get; set; }
public DbSet<Course> Courses { get; set; }
public DbSet<Book> Books { get; set; }
public DbSet<Review> Reviews { get; set; }
public DbSet<Location> Locations { get; set; }
public DbSet<JobAnnouncement> JobAnnouncements { get; set; }
public DbSet<Skill> Skills { get; set; }
public DbSet<InterviewQuestion> InterviewQuestions { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
modelBuilder.Properties()
.Where(p => p.Name == p.ReflectedType.Name + "Id")
.Configure(p => p.IsKey());
modelBuilder.Properties<string>()
.Configure(p => p.HasColumnType("varchar"));
modelBuilder.Properties<string>()
.Configure(p => p.HasMaxLength(1000));
modelBuilder.Entity<JobAnnouncement>()
.HasMany(c => c.Skills).WithMany(i => i.JobAnnouncements)
.Map(t => t.MapLeftKey("JobAnnouncementId")
.MapRightKey("SkillId")
.ToTable("JobAddsSkills"));
modelBuilder.Configurations.Add(new UserConfiguration());
modelBuilder.Configurations.Add(new ArticleConfiguration());
modelBuilder.Configurations.Add(new UserTaskConfiguration());
modelBuilder.Configurations.Add(new RoleConfiguration());
modelBuilder.Configurations.Add(new CompanyConfiguration());
modelBuilder.Configurations.Add(new CourseConfiguration());
modelBuilder.Configurations.Add(new BookConfiguration());
modelBuilder.Configurations.Add(new ReviewConfiguration());
modelBuilder.Configurations.Add(new LocationConfiguration());
modelBuilder.Configurations.Add(new JobAnnouncementConfiguration());
modelBuilder.Configurations.Add(new SkillConfiguration());
modelBuilder.Configurations.Add(new IntreviewQuestionConfiguration());
base.OnModelCreating(modelBuilder);
}
public override int SaveChanges()
{
foreach (var entry in ChangeTracker.Entries().Where(entry => entry.Entity.GetType().GetProperty("DateRegistered") != null))
{
if (entry.State == EntityState.Added)
{
entry.Property("DateRegistered").CurrentValue = DateTime.Now;
}
if (entry.State == EntityState.Modified)
{
entry.Property("DateRegistered").IsModified = false;
}
}
foreach (var entry in ChangeTracker.Entries().Where(entry => entry.Entity.GetType().GetProperty("DateAdded") != null))
{
if (entry.State == EntityState.Added)
{
entry.Property("DateAdded").CurrentValue = DateTime.Now;
}
if (entry.State == EntityState.Modified)
{
entry.Property("DateAdded").IsModified = false;
}
}
foreach (var entry in ChangeTracker.Entries().Where(entry => entry.Entity.GetType().GetProperty("IsActive") != null))
{
if (entry.State == EntityState.Added)
{
entry.Property("IsActive").CurrentValue = true;
}
}
foreach (var entry in ChangeTracker.Entries().Where(entry => entry.Entity.GetType().GetProperty("IsRead") != null))
{
if (entry.State == EntityState.Added)
{
entry.Property("IsRead").CurrentValue = false;
}
}
foreach (var entry in ChangeTracker.Entries().Where(entry => entry.Entity.GetType().GetProperty("Status") != null))
{
if (entry.State == EntityState.Added)
{
entry.Property("Status").CurrentValue = "New";
}
}
return base.SaveChanges();
}
}
Entity Framework 可以在没有连接字符串的情况下工作,尽管我更愿意控制以避免这种情况并执行 web.config transforms。
如果您在上下文构造函数中不提供任何内容,您将获得一个 SQL Express 数据库(.\SqlExpress 实例),如果 SQL express 在本地安装。否则,您会在您的用户配置文件文件夹或 \App_Data 文件夹中获得一个 localDb。我相信数据库是以上下文命名的。
如果您在构造函数中提供一个名称,它将查找具有该名称的连接字符串,但如果找不到,它会遵循上述规则,但将构造函数值指定为数据库的名称。这是你现在的情况。
简而言之(为时已晚),要解决您的问题,请将上下文构造函数更改为连接字符串的名称。
public CareerTrackContext()
: base("freeaspconnection")
{
}
有关 EF 如何连接的信息,请参阅 here。
我首先通过代码使用 EF 6.1.2 编写了我的应用程序。输入命令 "Update Database" 后,数据库已在我的 Microsoft SQL Server 2017 中创建。到目前为止一切顺利。但是,我从未在我的 app.config(来自 class 库)中看到我的数据库的连接字符串。它只是不存在,但是,令我惊讶的是它有效。它完美地连接到我的本地服务器。
现在,我已经将我的数据库移动到云端,因此我有一个连接字符串。我已将我的连接字符串复制粘贴到应用程序配置中,但它仍然指向初始服务器。
我的 app.config 看起来像这样:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<!--For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468-->
</configSections>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
I tried putting the connection string but it takes no effect. It still points to the local server. I have even deleted everything, and pasted my connection string but no success.
Any ideas of how to add my connection string so that it will point to the database from the cloud?
**UPDATE**:
The web.config as Roman requested. I have put the connection string there but it makes no difference (yes I am am aware of the 'X'-s, I don't wanna share the database :-) ):
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="freeaspconnection" connectionString="Server=XXXX;Database=XXXXXX;uid=liviusosu;pwd=;" providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="NumberOfUserTasksPerPage" value="7" />
<add key="NumberOfArticlesPerPage" value="10" />
<add key="NumberOfCoursesPerPage" value="10" />
<add key="NumberOfJobAnnouncementsPerPage" value="30" />
<add key="NumberOfInterviewQuestionsPerPage" value="30" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" maxRequestLength="1048576" />
<authentication mode="Forms">
<forms loginUrl="User/LogIn" timeout="300" />
</authentication>
</system.web>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701" />
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+" />
</compilers>
</system.codedom>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
这里是 DBContext
public class CareerTrackContext : DbContext
{
public CareerTrackContext()
: base("CareerTrack")
{
}
public DbSet<User> Users { get; set; }
public DbSet<Article> Articles { get; set; }
public DbSet<UserTask> UserTasks { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<Company> Companies { get; set; }
public DbSet<Course> Courses { get; set; }
public DbSet<Book> Books { get; set; }
public DbSet<Review> Reviews { get; set; }
public DbSet<Location> Locations { get; set; }
public DbSet<JobAnnouncement> JobAnnouncements { get; set; }
public DbSet<Skill> Skills { get; set; }
public DbSet<InterviewQuestion> InterviewQuestions { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
modelBuilder.Properties()
.Where(p => p.Name == p.ReflectedType.Name + "Id")
.Configure(p => p.IsKey());
modelBuilder.Properties<string>()
.Configure(p => p.HasColumnType("varchar"));
modelBuilder.Properties<string>()
.Configure(p => p.HasMaxLength(1000));
modelBuilder.Entity<JobAnnouncement>()
.HasMany(c => c.Skills).WithMany(i => i.JobAnnouncements)
.Map(t => t.MapLeftKey("JobAnnouncementId")
.MapRightKey("SkillId")
.ToTable("JobAddsSkills"));
modelBuilder.Configurations.Add(new UserConfiguration());
modelBuilder.Configurations.Add(new ArticleConfiguration());
modelBuilder.Configurations.Add(new UserTaskConfiguration());
modelBuilder.Configurations.Add(new RoleConfiguration());
modelBuilder.Configurations.Add(new CompanyConfiguration());
modelBuilder.Configurations.Add(new CourseConfiguration());
modelBuilder.Configurations.Add(new BookConfiguration());
modelBuilder.Configurations.Add(new ReviewConfiguration());
modelBuilder.Configurations.Add(new LocationConfiguration());
modelBuilder.Configurations.Add(new JobAnnouncementConfiguration());
modelBuilder.Configurations.Add(new SkillConfiguration());
modelBuilder.Configurations.Add(new IntreviewQuestionConfiguration());
base.OnModelCreating(modelBuilder);
}
public override int SaveChanges()
{
foreach (var entry in ChangeTracker.Entries().Where(entry => entry.Entity.GetType().GetProperty("DateRegistered") != null))
{
if (entry.State == EntityState.Added)
{
entry.Property("DateRegistered").CurrentValue = DateTime.Now;
}
if (entry.State == EntityState.Modified)
{
entry.Property("DateRegistered").IsModified = false;
}
}
foreach (var entry in ChangeTracker.Entries().Where(entry => entry.Entity.GetType().GetProperty("DateAdded") != null))
{
if (entry.State == EntityState.Added)
{
entry.Property("DateAdded").CurrentValue = DateTime.Now;
}
if (entry.State == EntityState.Modified)
{
entry.Property("DateAdded").IsModified = false;
}
}
foreach (var entry in ChangeTracker.Entries().Where(entry => entry.Entity.GetType().GetProperty("IsActive") != null))
{
if (entry.State == EntityState.Added)
{
entry.Property("IsActive").CurrentValue = true;
}
}
foreach (var entry in ChangeTracker.Entries().Where(entry => entry.Entity.GetType().GetProperty("IsRead") != null))
{
if (entry.State == EntityState.Added)
{
entry.Property("IsRead").CurrentValue = false;
}
}
foreach (var entry in ChangeTracker.Entries().Where(entry => entry.Entity.GetType().GetProperty("Status") != null))
{
if (entry.State == EntityState.Added)
{
entry.Property("Status").CurrentValue = "New";
}
}
return base.SaveChanges();
}
}
Entity Framework 可以在没有连接字符串的情况下工作,尽管我更愿意控制以避免这种情况并执行 web.config transforms。
如果您在上下文构造函数中不提供任何内容,您将获得一个 SQL Express 数据库(.\SqlExpress 实例),如果 SQL express 在本地安装。否则,您会在您的用户配置文件文件夹或 \App_Data 文件夹中获得一个 localDb。我相信数据库是以上下文命名的。
如果您在构造函数中提供一个名称,它将查找具有该名称的连接字符串,但如果找不到,它会遵循上述规则,但将构造函数值指定为数据库的名称。这是你现在的情况。
简而言之(为时已晚),要解决您的问题,请将上下文构造函数更改为连接字符串的名称。
public CareerTrackContext()
: base("freeaspconnection")
{
}
有关 EF 如何连接的信息,请参阅 here。