Setup lokalny
Migracje w .Net core EF dodaje się z command line’a. Ale żeby móc to zrobić, wpierw potrzebujemy zainstalować narzędzia do tworzenia migracji i baz EF.
Jak to zrobić opisano tutaj:
Ważne, żeby nie zapomnieć RĘCZNIE wkleić do project file poniższej referencji: https://stackoverflow.com/a/47079152/148158
Następnie:
1 2 3 4 |
dotnet add package Microsoft.EntityFrameworkCore.Design dotnet restore |
I to pozwala już mi na stworzenie pierwszej migracji:
1 2 3 4 |
dotnet ef migrations add Initial dotnet ef database update Initial |
Resultat: Jest baza!
Mogę od teraz dodawać konta testowe, które są w stanie przetrwać restart aplikacji. Albo innymi słowy – mam już CR_D z CRUD 🙂
Setup na AppHarbor
O ile lokalnie poszło gładko, to z AppHarbor musiałem się trochę namęczyć.
Najpierw zainstalowałem SQL Server AddOn
A potem już tylko próbowałem zrozumieć co jest napisane w artykule o używaniu Sequelizera
Zmarnowałem naprawdę dużo czasu, bo uwierzyłem że AppHarbor podmieni automatycznie mój connection string zdefinowany w appsettings.json, jeżeli tylko nadam mu odpowiedni klucz. Tę samą nazwę wystarczyłoby tylko ustawić jako ‘connection string alias’ w konfiguracji SQL add-ona, i zadziałałaby MAGIA.
If you want AppHarbor to replace the connectionString you have to define one with the relevant name in your application’s configuration files.
Więc dodałem connection string do mojego pliku konfiguracyjnego.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{ "Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Warning" } }, "ConnectionStrings": { "microbank_connection": "Server=(local)\\SQLEXPRESS;Database=microbank;Trusted_Connection=True;" } } |
Następnie odczytałem wartość tego ustawienia w metodzie ConfigureServices
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public void ConfigureServices(IServiceCollection services) { var builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json"); var connectionStringConfig = builder.Build(); var connectionString = connectionStringConfig.GetConnectionString("microbank_connection"); services.AddMvc(); services.AddDbContext<MicroBankContext>(options => options.UseSqlServer(connectionString)); } |
Ale magia nie chciała działać, i po wielu próbach poddałem się i postanowiłem wykorzystać wyjście B, czyli wykorzystać fakt, że AppHarbor ustawia zmienną systemową o nazwie SQLSERVER_CONNECTION_STRING.
Ostatecznie działający kod który wykorzystuje bazę SQL Server na AppHarbor wygląda tak:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.EntityFrameworkCore; using microbank.Data; using System.IO; namespace microbank { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddMvc(); var connectionString = _getConnectionString(); _migrateDatabase(connectionString); services.AddDbContext(options => options.UseSqlServer(connectionString)); } private static void _migrateDatabase(string connectionString) { var optionsBuilder = new DbContextOptionsBuilder(); optionsBuilder.UseSqlServer(connectionString); using (var context = new MicroBankContext(optionsBuilder.Options)) { context.Database.Migrate(); } } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); } app.UseStaticFiles(); app.UseMvc(); } private string _getConnectionString(){ // Get connection string from injected env variable // fallback to the connection string from appconfig var injectedConnectionString = Environment.GetEnvironmentVariable("SQLSERVER_CONNECTION_STRING"); if(!string.IsNullOrWhiteSpace(injectedConnectionString)) return injectedConnectionString; var builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json"); var connectionStringConfig = builder.Build(); var connectionString = connectionStringConfig.GetConnectionString("microbank_connection"); return connectionString; } } } |
Be First to Comment