I have a localdb that is working just fine on my development machine, however when I tried to test the app on another machine, I found that somehow changes do not take effect on the dB.
What could make entity framework behave differently on my machine than in the other one?
Here is my DbContext
public DataContext() : base("name=DBConnectionString")
{
Database.SetInitializer(new DataInitializer());
}
And the DataInitializer class:
public class DataInitializer: DropCreateDatabaseIfModelChanges<DataContext>
{
public DataInitializer()
{
}
protected override void Seed(DataContext context)
{
//Insert some seed data
Console.WriteLine("Seeding db...");
...
base.Seed(context);
}
}
and the connection string:
<connectionStrings>
<add name="DeltaDBConnectionString"
connectionString="Server=(localdb)\v11.0;Integrated Security=true;
AttachDbFileName=|DataDirectory|\DeltaDB.mdf;"
providerName="System.Data.SqlClient"/>
</connectionStrings>
Related
I've got a code base that uses EF Core and Dapper to perform actions on a database.
I want to set up a new copy of the site to develop some features and I want this site to connect to a new isolated copy of the database (dbConnectionDEBUG).
At the moment, I use the following setup:
startup.cs
...
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("dbConnectionMain")));
services.Configure<ConnectionStrings>(Configuration.GetSection("ConnectionStrings"));
...
I have a ConnectionStrings class which is being populated correctly via the DI in startup:
public class ConnectionStrings
{
public string dbConnectionMain { get; set; }
public string dbConnectionDEBUG { get; set; }
public ConnectionStrings()
{
this.dbConnectionMain = "";
this.dbConnectionDEBUG = "";
}
}
Then, throughout my controllers/services I have access to ConnectionStrings and 99% of the time I'm doing the following to make DB calls:
using (var conn = new SqlConnection(_connectionStrings.dbConnectionMain))
{
conn.Open();
...
This would amount to a lot of code changes if I were to want to switch over to the 'DEBUG' db.
How do I easily switch between the connection strings in my code depending on what version of the system I'm working on.
If I could somehow do this dynamically that'd be great. The obvious determining factor would be the URL the site is operating on.
Alternatively, (as a single change) do I just manually change the connection string at the source (e.g keystore/appsettings). I'm not keen on this as it leaves room for human error.
Update (2)
Based on what #Nkosi mentioned I am pursuing this path:
Have one connection string 'Id' (i.e. dbConnection) used throughout
Differentiate the connection string value within this based on the environment the app is running/deployed in
I have another question:
If I have the following...
"MYAPPNAME": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:12345/;https://myapptestdomain.com/"
}
and:
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, config) =>
{
IHostingEnvironment env = context.HostingEnvironment;
config.AddJsonFile($"appsettings.{env.EnvironmentName.ToLower()}.json", optional: true);
})
.UseStartup<Startup>();
...will this automatically pick up my site is in the Development mode based on the applicationUrl values OR will I have to manually add ASPNETCORE_ENVIRONMENT with a value Development on the server I deploy the app to?
Additional: My app is running in an Azure App Service.
Update (3) - Mission Complete
Just to finalise this question (in case anyone needs to know this), I have the following setup based on recommendations made by #Nkosi.
Connection String - I have one connection string Id/name dbConnection which is used in all appSettings (see below)
App Settings
I have a default appSettings.json with dbConnection that looks at the live database
I have an additional appSettings.Playground.json file with dbConnection that looks at my testing database
Azure - App Service - On my playground development slot I have added an App Setting for ASPNETCORE_ENVIRONMENT with the value 'Playground'
In my Program.cs file I have:
config.AddJsonFile($"appsettings.json", optional: true,reloadOnChange: true);
and
config.AddJsonFile($"appsettings.{env.EnvironmentName.ToLower()}.json", optional: true,reloadOnChange: true);
Just to note, I do also initialise a Vault on Azure which stores all my Keys and Secrets for the Azure based apps. Locally User Secrets is used.
ASP.NET Core reads the environment variable ASPNETCORE_ENVIRONMENT at app startup and stores the value in IHostingEnvironment.EnvironmentName.
Since the environment is being loaded, then it should be available from the hosting environment via the builder context
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, config) => {
string environment = context.HostingEnvironment.EnvironmentName; //get current environment
//load config based on environment.
config.AddJsonFile($"appsettings.{environment}.json", optional: true);
//...
})
//...
Reference Use multiple environments in ASP.NET Core
For simple apps and to keep the connection strings away from my repository I use preprocessor statements plus PATH/System Variables and for release I provide a connection string within the settings.json.
#define USE_FEATURE_X
using System;
namespace MyNamespace {
internal static class StaticConnectionStringFactory {
public static string GetConnectionString() {
#if DEBUG && !USE_FEATURE_X
var connectionString = Environment.GetEnvironmentVariable("CNNSTR_SQL_XYZ", EnvironmentVariableTarget.User);
#elif DEBUG && USE_FEATURE_X
var connectionString = Environment.GetEnvironmentVariable("CNNSTR_SQL_ABC", EnvironmentVariableTarget.User);
#else
var connectionString = Environment.GetEnvironmentVariable("SqlConnectionString", EnvironmentVariableTarget.Process);
#endif
return connectionString;
}
}
}
I think if you add 2 connection for debug and main then you will have face some difficulty because more member working in you team. may be some own wrongly use release mode for code development.
you can try this webconfig method:
public class ConnectionStrings
{
public string dbConnection { get; set; }
public ConnectionStrings()
{
bool Ismain = bool.Parse(System.Configuration.ConfigurationManager.AppSettings["HasLive"]);
if (Ismain)
{
dbConnection = "";// get Main connectionstring
}
else
{
dbConnection = "";// get Debug connectionstring
}
}
}
web.config:
<connectionStrings>
<add name="dbConnectionMain" connectionString="" providerName="System.Data.SqlClient" />
<add name="dbConnectionDEBUG" connectionString="" roviderName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="HasLive" value="false"/>
</appSettings>
</connectionStrings>
i ve big problems running enterprise library data access block with net core 1 (dnx 4.5.1)
How can i setup the default connection string for entlib
my appsettings.json
"ConnectionString": "Server=localhost\sqlexpress;Initial Catalog=blind;User Id=blind;Password=blind"
Here is my problem (no default connectionstring)
Database db = DatabaseFactory.CreateDatabase();
how can i pass the appsettings ConnectionString to the entlib databasefactory
any help would be greatly appreciated
I know it's an old question, but I have a similar setup (but using .NET Core 2.0) and it took me awhile to figure out how to set the default database connection without using the web.config to manage it.
What I did was include the default database and all of the connection strings in the appsettings.json and then in my Startup class I read the appsettings.json into an object that I defined to store the default db name and the connection strings and configure the default + named database using DatabaseFactory.SetDatabase.
DatabaseFactory.SetDatabases() Definition
public class DataConfiguration
{
public string DefaultDatabase { get; set; }
public List<ConnectionStringSettings> ConnectionStrings { get; set; }
}
public class Startup
{
public Startup(IConfiguration configuration)
{
//Get the Database Connections from appsettings.json
DataConfig = configuration.Get<DataConfiguration>();
var defaultDb = DataConfig.ConnectionStrings?.Find(c => c.Name == DataConfig.DefaultDatabase);
DatabaseFactory.SetDatabases(() => new SqlDatabase(defaultDb.ConnectionString), GetDatabase);
Configuration = configuration;
}
public Database GetDatabase(string name)
{
var dbInfo = DataConfig.ConnectionStrings.Find(c => c.Name == name);
if (dbInfo.ProviderName == "System.Data.SqlClient")
{
return new SqlDatabase(dbInfo.ConnectionString);
}
return new MySqlDatabase(dbInfo.ConnectionString);
}
}
Whenever there is documentation, I always suggest reading it as it is usually good. This is one of those examples, check out the "Getting Started with ASP.NET 5 and Entity Framework 6". There are several things that you need to do to ensure that you are correctly configured.
Setup your connection string and DI.
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
}
Also, notice the path in the configuration, it seems to differ from yours.
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped((_) =>
new ApplicationDbContext(
Configuration["Data:DefaultConnection:ConnectionString"]));
// Configure remaining services
}
I've created very simple MVC5 project with two Web roles . webRole1 with local DB which was created by code first (and generate the view by scaffold) this is working fine ,I was able to run it get view data and create data in the local DB.
Now I created very simple API in the WebRole1 to read the data from the DB which is working and I get the data via the API
I created WebRole2 and The problem is that I dont able to read the data in from this API (which is in web role1 ) in webRole2,How should I do that?I getting null for the key that I provided which is exist in DB
I can share the project in one drive if its OK.
This is the model of WebRole1
namespace WebRole1.Models
{
public class User
{
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public string UserId { get; set; }
public string FirstName { get; set; }
}
public class ConfigModelDbContext : DbContext
{
public ConfigModelDbContext()
: base("DefaultConnection")
{
}
public DbSet<User> User { get; set; }
}
}
This is the connection string
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\User.mdf;Initial Catalog=Users;Integrated Security=True" providerName="System.Data.SqlClient" />
</connectionStrings>
This is the simple API which read the data from the local DB (the data found if I call this API from webRole1
namespace WebRole1.Models
{
public class UserApi
{
private ConfigModelDbContext db = new ConfigModelDbContext();
public User getDbData()
{
User user = db.User.Find("user1");
return user;
}
}
}
Answered here by Russriguez:
Configure the second WebRole to point at the .mdf in the first WebRole (MVC project), e.g.
<connectionStrings>
<add name="Connection1" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=C:\Path\To\The\Database\Person.mdf;Initial Catalog=Persons;Integrated Security=True" providerName="System.Data.SqlClient" />
</connectionStrings>
replace "C:\Path\To\The\Database\Person.mdf" with the actual full path
to the database file that is in WebRole1's App_Data directory.
Only problem is that this is an absolute path, so all developers need their repository in the same place. Not ideal, but I couldn't get relative paths to work. I tried:
..\..\..\..\..\..\[project-with-db]\App_Data\[db-name].mdf
assuming that the base directory of the second web role would be:
[src-root]\[azure-project]\csx\Debug\roles\[web-role-project-2]\approot
I have a connection string:
<add name="Gini" providerName="System.Data.SqlClient" connectionString="user id=user;Password=pa55;Data Source=server;Database=gini" />
I want EF to be able to control the creation of the database and updates through migrations so I'm letting it have complete control over the DB.
My contact class looks like the following:
public class GiniContext : DbContext
{
public DbSet<UserSession> UserSessions { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new UserSessionConfiguration());
}
public GiniContext() : base("Gini")
{
Database.Create();
}
}
I would expect this to create a database called "gini" on the server called "server" using the username and password as above but it's creating it on the (LocalDB)\v11.0 instance.
What am I doing wrong?
If you have two projects like a Class Library for Objects and a Web Application referencing it. You ll need to add the connection from app.config to the web.config in your web application.
I am not planning to use EF Code First in an MVC Website. I am looking to Utilize it in a App that has a WPF Client.
Projects are setup as
ContactManager.Core // Contains all
Entities(dll)
ContactManager.Data // Contains
the DataContext and other data
related Services(dll)
ContactManager.Services // Business
components (dll)
ContactManager.Client // WPF
Application
I am unable to generate a SQLExpress or SQLCE 4.0 DB. I am more interested in compact version db. I am not getting any error except my unit tests fail because it tries to connect a db that doesnt exist.
I found out the answer 2 Options:
Option 1:
In your DbContext you specify the connection strings in the base constructor:
public class RecetteContext : DbContext
{
public RecetteContext()
:base("<YourConnectionString HERE>")
{
}
public DbSet<Categorie> Categories { get; set; }
public DbSet<Recette> Recettes { get; set; }
}
}
Option 2:
The one I used, you give you connection string a name in the DbContext base constructor:
public RecetteContext()
: base("RecettesDatabase")
{ }
And in your App.Config file you add a ConnectionString with the same name:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="RecettesDatabase"
connectionString="Data Source=RecettesDB.sdf"
providerName="System.Data.SqlServerCe.4.0"/>
</connectionStrings>
</configuration>
Hope it solved your issue!