Deploy a WPF program and update the database if required - c#

I'm creating a WPF application that uses a LocalDB instance (which is provided by the ClickOnce installer).
The program uses a database to store userdata. When the application is deployed for the very first time, I want to create a LocalDB where some data is inserted upon initialization.
When I later provide an update to the program (which may include schema changes), I do not want to lose any userdata.
I'm using EF Code-First and this is my DbContext:
public class MyContext : DbContext
{
public DbSet<Stuff> Premises { get; set; }
public DbSet<Person> Persons { get; set; }
private static MyContext _Current;
public static MyContext Current
{
get
{
if (_Current == null)
{
_Current = new MyContext();
}
return _Current;
}
}
protected MyContext()
{
//Some data to insert on the first time
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Stuff>().HasMany(p => p.Persons).WithRequired(m => m.Stuff);
}
}
App.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<connectionStrings>
<add name="MyContext"
connectionString="data source=(LocalDB)\mssqllocaldb;Integrated Security=True"
providerName="System.Data.SqlClient"/>
</connectionStrings>
<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>
</configuration>
Am I correct in thinking that adding my development .mdf file will always overwrite the userdata when I update via ClickOnce?
How can I let EF create the schema for the first time, update when there's changes, and never lose any userdata?

Related

How to handle "No connection string named 'RestaurentEntities' could be found in the application config file" in WinForms

I am trying a project on WinForms. I made a Form name Dashboard and User Control name DashboardScreen.
Dashboard basically will have many User Controls on it like DashboardScreen, InventoryScreen, SettingsScreen etc. These screens are small and Dock in main parent form Dashboard so when user click on button, corresponding user control comes to the front using DashboardScreen.BringToFront()
These user controls are implementing Entity Framework V 6.4.0 User controls and Main Dashboard Form works fine when I do not use Entity Framework on these controls. Whenever I use Entity Framework as RestaurentEntities DB = new RestaurentEntities(); to utilize database services the Main Dashboard Form gives the following Error in Design Mode.
No connection string named 'RestaurentEntities' could be found in the application config file.
Second Error is
The variable 'dashboardScreen' is either undeclared or was never assigned.
Given is my configuration file.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<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>
<connectionStrings><add name="RestaurentEntities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string="data source=YASIR\SQLDEVENV;initial catalog=Restaurent;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>
if you want to drag and drop a UserControl in a form and the control in the constructor method or OnLoad method has access to EntityFramework and the EntityFramework access is created by referenced project you must include into your code something like:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (!DesignMode)
{
//access to EntityFramework
}
}
Change your connectionStrings to below:
<connectionStrings>
<add name="RestaurentEntities"
connectionString="data source=YASIR\SQLDEVENV;initial catalog=Restaurent;integrated
security=True;MultipleActiveResultSets=True;App=EntityFramework"
providerName="System.Data.SqlClient" />
</connectionStrings>
And make sure that
your Dbcontext constructor is like
public RestaurentEntities ()
: base("name=RestaurentEntities")
{
}

Migrate database generated by entity framework to sqlserver

I made a application with database generated by entity framework(code first) and now I want to make my application working on other computer. I instaled sqlserver there and made all the tables in the database (I am working just with localhost database). Now I wanted to connect my database with application, I thought that all what I need to do is just change connection string. But I am not able to connect to my database.
Here is how looks my app.config file:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<connectionStrings>
<add name="InzerceConnection" connectionString="Data source=VRBASPC\SQLEXPRESS;Initial Catalog=AdvertisingSystemDB;Trusted_Connection=true;MultipleActiveResultSets=true" />
<!--This is how my connection string works by default <add name="InzerceConnection" connectionString="Server=(localdb)\\MSSQLLocalDb;Database=Inzerce_Dev;Trusted_Connection=true;MultipleActiveResultSets=true" />-->
<!--<add name="InzerceConnection" connectionString="Server=localhost\SQLEXPRESS;Database=AdvertisingSystemDB;Trusted_Connection=true;MultipleActiveResultSets=true" />-->
</connectionStrings>
<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>
</configuration>
I tried a lot of combination of connection string, but none worked.
I am not sure how to setup my config file to connect to database.
Thank you for any advice.
Sory for my english its not my native language.
In your context override the OnConfiguring method.
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
string connstr = ConfigurationManager.ConnectionStrings["InzerceConnection"].ToString();
optionsBuilder.UseSqlServer(connstr);
}
Check in your database context.
Database context and name attributes should be the same.
For Example
public class DatabaseContext : DbContext
{
public DbSet<Content> Contents { get; set; }
public DbSet<Category> Categories { get; set; }
public DatabaseContext()
{
Database.SetInitializer(new MyInitializer());
}
}
ConnectionStrings in your app.config
<connectionStrings>
<add name="DatabaseContext" providerName="System.Data.SqlClient" connectionString="Data source=VRBASPC\SQLEXPRESS;Initial Catalog=AdvertisingSystemDB;Trusted_Connection=true;MultipleActiveResultSets=true" />
</connectionStrings>

Entity Code First Error (Mysql)

When I run "Enable-Migrations -Force" command on my Class Library project, I see following error.
Note: Mysql.Data and Mysql.Data.Entity has been installed.
System.TypeInitializationException: The type initializer for
'System.Data.Entity.Migrations.DbMigrationsConfiguration`1' threw an
exception. ---> System.TypeLoadException: Inheritance security rules
violated by type: 'MySql.Data.Entity.MySqlEFConfiguration'. Derived
types must either match the security accessibility of the base type or
be less accessible.
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>
<connectionStrings>
<add name="DefaultConnection" connectionString="Server=10.10.10.10;Database=dbName;Uid=user;Pwd=p;" providerName="MySql.Data.MySqlClient" />
</connectionStrings>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<!--<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />-->
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6, Version=6.10.4.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d">
</provider></providers>
</entityFramework>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
</configuration>
DbContext.cs
[DbConfigurationType(typeof(MySqlEFConfiguration))]
public class MyDbContext : DbContext
{
public MyDbContext() : base("DefaultConnection")
{
}
public DbSet<User> Users { get; set; }
public DbSet<Board> Boards { get; set; }
}
I'm having exactly the same problem in both VS 2015 and VS 2017, have tried everything and nothing works :(
--- Edit
I get the job done after downgrade the MySQL.Data to 6.8.8.0 . Worked both VS 2015 and VS 2017.
[DbConfigurationType(typeof(MySqlEFConfiguration))]
public class Context : DbContext
{
public Context() : base("MyContext")
{
}
public DbSet<Foo> foo;
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Foo>();
}
}

Entity Framework not saving changes to a Local DB

I'm new to C# and Entity Framework and I'm trying to write an application to improve my knowledge.
I think I've set up everything correctly and I don't get any type of error. The problem is that I can not add a new record to localDb in Visual Studio 2017.
Any ideas? Thanks in advance.
Here is my code
private void Save_btn_Click(object sender, EventArgs e)
{
var context = new Database1Entities();
var aMemberdef = new Members()
{
FirstName = Name_txt.Text,
LastName = LastName_txt.Text
};
context.Members.Add(aMemberdef);
context.SaveChanges();
}
and here my 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" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<connectionStrings>
<add name="Database1Entities"
connectionString="metadata=res://*/EF.Model1.csdl|res://*/EF.Model1.ssdl|res://*/EF.Model1.msl;provider=System.Data.SqlClient;provider connection string="data source=(LocalDB)\MSSQLLocalDB; attachdbfilename=|DataDirectory|\Data\Database1.mdf; initial catalog=Database1; integrated security=True;MultipleActiveResultSets=True;App=EntityFramework""
providerName="System.Data.EntityClient" />
</connectionStrings>
<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 think there is some mistake in the app config file but the connection string was generated by entity framework. So I'm stuck MyDB Structure
Because your localdb is copied to bin folder every time you run it. It gets overwritten everytime you run/debug it. Main file in the project folder is not updated.
For detailed answer:
https://social.msdn.microsoft.com/Forums/en-US/393bddc6-0b85-4c27-9475-27172e50d2d9/entity-framework-doesnt-save-new-record-into-database?forum=adodotnetentityframework

Entity Framework To A Remote Server (Connection String)

I have installed EF Version 6.1.3 on all my projects. I then created a model class, a context class, and installed a MSSQL database on my local computer (I did not have done anything else). Everything worked just perfectly (somehow it knew about my local database).
Model class:
public class Account
{
public int Id { get; set; }
public string Name{ get; set; }
}
DataContext class:
public class MyClassDataContext: DbContext
{
public DbSet<Account> Accounts{ get; set; }
}
App.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=xxxxxx" requirePermission="false" />
</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 then tried to move it to a remote database and it doesn't work. I tried everything.
What is the right approach, to get the job done?
EDIT:
I tried this connection string and nothing happens. The app still tries to connect with the local database.
<connectionStrings>
<add name="MyClassDataContext" connectionString="Data Source=MyRemoteServer;Initial Catalog=MyRemoteCatalog;Integrated Security=true" providerName="System.Data.SqlClient"/>
</connectionStrings>
<configSections>
You need to create either make sure that your connections string's name is the fully qualified name of your context, or create an explicit default constructor for your context. Since you mentioned it in the comments, the link you provided isn't working for you because you're using code-first. Try this link instead.
Below is a fully functional console app that can demonstrate how it should work, along with the config file. This will use our local SQLServer installation, but not the SQLExpress. It should work fine for any remote database as well.
Note that in the previous app config that I had posted, I put the connection string section at the top. That is incorrect: configSections must be the first node.
namespace TestApp
{
public class Account
{
public int Id { get; set; }
public string Name { get; set; }
}
public class MyClassDataContext : DbContext
{
public DbSet<Account> Accounts { get; set; }
}
class Program
{
static void Main(string[] args)
{
using (var x = new MyClassDataContext())
{
x.Accounts.Add(new Account { Name = "Drew" });
x.SaveChanges();
var y = x.Accounts;
foreach (var s in y)
{
Console.WriteLine(s.Name);
}
}
Console.ReadKey();
}
}
}
The configuration file:
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<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="ConsoleApplication4.MyClassDataContext" connectionString="Data Source=.;Initial Catalog=MyClass;Integrated Security=true" providerName="System.Data.SqlClient"/>
</connectionStrings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<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>
</configuration>

Categories

Resources