C
C#ā€¢9mo ago
Kroks

ā” EFCore SQLITE Migrations on Server

I am developing with EFCore locally, however I copied the .db over to the server and on the server its filling the database with data. Now I have the issue that I need to change some table, so I was changing the corresponding model locally. Now my question, what would be the proper way to apply these changes to the .db that is on the server?
62 Replies
Kroks
Kroksā€¢9mo ago
on the server I have only the build, not the source
Pobiega
Pobiegaā€¢9mo ago
You can use runtime migrations, aka running them via code inside your app as part of your startup
Kroks
Kroksā€¢9mo ago
oh ok. The migration files I need to move them on the server too I assume?
Pobiega
Pobiegaā€¢9mo ago
Using Efcore they are part of your code already Assuming code first, at least If you are using DB first, idk
Kroks
Kroksā€¢9mo ago
Ok wait I will try to explain what I did so far first. What I did: - Programmed locally - Set up the database locally (with EnsureCreated method, not with any command) - Copied the database to the server - The server runs a program which inserts data into the database copied. The problem: - Now I found a bug in the implementation, I want to change a table. - I change the model locally in the respective class (add a property). - How do I put the new database on the server without losing the existing data that is already in the database on the server? Like what is the best way to handle it, whats the best workflow now? Maybe my setup was from the beginning on wrong, not sure.
UltraWelfare
UltraWelfareā€¢9mo ago
Since you used EnsureCreated, then you won't be able to use migrations (you should def read on that). Right now your only solution is to manually write the SQL queries and apply them to your database
Kroks
Kroksā€¢9mo ago
Got it, its not a big deal to drop the current one. Just want to know what the best way to proceed. I will use migrations next time, but how would I update it on the server each time. Kinda seems annoying
UltraWelfare
UltraWelfareā€¢9mo ago
Migrations are either applied by accessing into the server and running dotnet ef database update or there is a Migrate() function on the context (or context.Database, i dont remember)
Kroks
Kroksā€¢9mo ago
for that I would need to always move the migration files that I generated locally
UltraWelfare
UltraWelfareā€¢9mo ago
so instead of EnsureCreated(), you can always use Migrate()
Kroks
Kroksā€¢9mo ago
to the server?
UltraWelfare
UltraWelfareā€¢9mo ago
Migration files are within the project They're .cs files and they're autogenerated
Kroks
Kroksā€¢9mo ago
yeah but on server end I have only the build files
UltraWelfare
UltraWelfareā€¢9mo ago
the build would include the migrations
Kroks
Kroksā€¢9mo ago
oh got it now
UltraWelfare
UltraWelfareā€¢9mo ago
so running .Migrate() will be fine I guess dotnet ef database update wouldn't work, since you don't have the source project in the server
Kroks
Kroksā€¢9mo ago
so each time I do a migration on my local, I can just build the project after doing it, then on server app calling just ".Migrate()" would update the DB on the server?
UltraWelfare
UltraWelfareā€¢9mo ago
But i'm not entirely sure
Kroks
Kroksā€¢9mo ago
yeah
UltraWelfare
UltraWelfareā€¢9mo ago
yep
Kroks
Kroksā€¢9mo ago
is it like the best way ? Maybe sqlite is like not the best for this purpose, maybe a cloud DB would do better but not sure like with a cloud db I can do the migration and "push" it on the cloud DB and then its auto synchronized on the server aswell as it uses the same cloud db
UltraWelfare
UltraWelfareā€¢9mo ago
Yeah but if you wanna prototype, or use different data you can't... if you add a column or change a column locally, the running server will explode it's not a good idea you should have different local and production databases
Kroks
Kroksā€¢9mo ago
yeah thats true
UltraWelfare
UltraWelfareā€¢9mo ago
it's not specific to sqlite it's an architectural problem and it's a bad idea to use the production database
Kroks
Kroksā€¢9mo ago
about this command I had a question too, how does it know the DB Path for updating the DB? is it parsing the context file and searching for data source string?
UltraWelfare
UltraWelfareā€¢9mo ago
afaik it's using appsettings.json or yeah if oyu have it inside the context it uses that i don't remember the priority
Kroks
Kroksā€¢9mo ago
Ok anyways. I will just do what you suggested. Do the migration locally, rebuild the project, put it on the server and use Migrate method at startup or what else I could do probably is just syncing via git, once migration done I push on git and then pull on server and then update the DB via that command on server would work too right?
UltraWelfare
UltraWelfareā€¢9mo ago
yeah
Kroks
Kroksā€¢9mo ago
Ok setted it up now. So basically my workflow currently is: - Changing stuff locally if needed - Generating migration files (via Add-Migration) - Push - Pull on Server - Update command on server is this correct?
Pobiega
Pobiegaā€¢9mo ago
not really you dont need the source on the server, you just need the published release migrations are literally code that is compiled just like your application code
Kroks
Kroksā€¢9mo ago
yeah ok got it, though I prefer to have the code on server too for some reasons. My approach would still work I assume
Pobiega
Pobiegaā€¢9mo ago
sure just add in a "build/publish app" after "pull on server" then šŸ™‚
Kroks
Kroksā€¢9mo ago
If I only have the builds (not the src) and I do the update command how does it search for the db path ? via reflection? it sounds weird to me
Pobiega
Pobiegaā€¢9mo ago
no, it uses the config file just like it does when you run it "with the source" it always compiles and resolves your context ĀÆ\_(惄)_/ĀÆ
Kroks
Kroksā€¢9mo ago
sorry but which one are you refering to
Pobiega
Pobiegaā€¢9mo ago
I assumed you used config files to store your connection string it doesnt matter thou it resolves the context
Kroks
Kroksā€¢9mo ago
No I didnt actually
Pobiega
Pobiegaā€¢9mo ago
the Add-Migration and Update-Database (or dotnet ef ...) commands all use your actual real context
Kroks
Kroksā€¢9mo ago
oh they are instantiating the context via reflection probably
Pobiega
Pobiegaā€¢9mo ago
they actually "start" part of your application to resolve the context yes
Kroks
Kroksā€¢9mo ago
that might also explain the error I had when I didnt have the default constructor could not instantiate ok now I understand it better.
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseSqlite($"Data Source=bot.db");
}
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseSqlite($"Data Source=bot.db");
}
here I hardcoded the path, however multiple projects use this DB library and the context, now I assume if I run it from A.exe it will not actually use the bot.db from the DB project path but it will search for it from A.exe directory. Whats the best way to go about this? I want all to use the same .db that is located in the DB project folder
Pobiega
Pobiegaā€¢9mo ago
it will. or actually, what? your db file shouldnt exist in a "project" the db file is a result of running the program/migrations
Kroks
Kroksā€¢9mo ago
yeah right I mean I just do the migration & update stuff in the Database project
Pobiega
Pobiegaā€¢9mo ago
if you have multiple consuming projects (think things that run, non-class libs) that use the same database, you will have issues with SQLite
Kroks
Kroksā€¢9mo ago
as it should be due to concurrency?
Pobiega
Pobiegaā€¢9mo ago
yes
Kroks
Kroksā€¢9mo ago
whats my best bet
Pobiega
Pobiegaā€¢9mo ago
using a real database sqlite is an in-process database
Kroks
Kroksā€¢9mo ago
SQL server?
Pobiega
Pobiegaā€¢9mo ago
Postgres, SQL Server are my two recommendations
Kroks
Kroksā€¢9mo ago
okay. Yeah I thought about that already. Thanks for claryfing again. MYSQL also fine?
Pobiega
Pobiegaā€¢9mo ago
not really in theory, yes, but its by far the worst SQL database ever written I see literally no reason to use it over postgres
Kroks
Kroksā€¢9mo ago
kk xD
UltraWelfare
UltraWelfareā€¢9mo ago
because the legacy app is written using mysql (cries internally)
Pobiega
Pobiegaā€¢9mo ago
with EF Core, its usually quite easy to switch šŸ™‚ but since you said legacy, its probably not ef core šŸ˜„
UltraWelfare
UltraWelfareā€¢9mo ago
it's a huge erp app and i just migrated it to dotnet after being on net framework. All of the SQL queries are handwritten (no ORM). So I reverse engineered the database using efcore tools and we're partially replacing the app part by part if we were to switch the whole application instantly to EF-Core it would take a year lol unfortunately not a path we can take, but at least mysql is usable ... anyways, that being said postgres is the best way to go forward
Kroks
Kroksā€¢9mo ago
bruh handwritten sql never again
Kroks
Kroksā€¢9mo ago
I just added a new DBSet and added the migration and this is what happened (in a completely unrelated model) when I tried to update it. As I said this column is completely independent from what is new, it worked before.
No description
Kroks
Kroksā€¢9mo ago
using postgres
Pobiega
Pobiegaā€¢9mo ago
thats not an EF error so it must be a postgres error
UltraWelfare
UltraWelfareā€¢9mo ago
Yep
Accord
Accordā€¢9mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.