Inhalte aufrufen

Profilbild
- - - - -

Add_Migration in Dev-Umgebung

plugin migration

Best Answer Marcus Gesing , 28 December 2022 - 11:26

In Smartstore 5 wird für Datenbank-Migrationen Fluent Migrator verwendet (nicht mehr Entity Framework Migrations).
 
Im DevTools Modul sind einige auskommentierte Beispiele zu sehen.
 
Das GoogleMerchantCenter Modul verwendet ebf. eine Migration, um zusätzliche Produktdaten in einer eigenen Datenbanktabelle zu speichern. Voraussetzungen, damit das gelingt, kann man sich dort abgucken. Dazu zählt vor allem die IDbContextConfigurationSource Implementierung.
 
Die Smartstore 5 Entwickler-Dokumentation befindet sich hier (noch unvollständig), z.B. Module, Creating a Domain entity. Ich hoffe, dass hilft erstmal weiter.
Go to the full post


  • Bitte melden Sie sich an, um eine Antwort zu verfassen.
5 Antworten zu diesem Thema

#1 Algorithman

Algorithman

    Advanced Member

  • Members
  • PunktPunktPunkt
  • 39 Beiträge

Geschrieben: 28 December 2022 - 09:40

Hallo,

 

Ich bin gerade am Evaluieren von neuen Shop-Systemen (wir haben noch 'ne alte Shopware laufen).

 

Dabei habe ich auch Smartstore gefunden und der Eindruck ist recht positiv.

Was ich allerdings machen müsste wäre eine Anpassung der Produkt-Daten.

Wir sind eine Brillen-Manufaktur, sprich unsere Artikel haben Farbe (über 1000 verschiedene) und alle möglichen Grössen.

Da kann/will ich dann mit Dropdowns nichts mehr machen. Da müssen Text-Felder (mit Default-Werten) her. Unsere Kunden kommen damit auch zurecht, soll ja als reiner B2B-Shop laufen.

Also muß ich irgendwie Custom-Felder und Tabellen in den ganzen Ablauf einbringen.

 

Dabei finde ich natürlich den Code-First-Ansatz sehr ansprechend. 

 

 

Soviel zur Prämisse.

 

Was mir momentan nicht gelingt ist, dass ich eine DB Migration anzustossen. 

Die Dokumentation zu Plugins ist momentan ja auch nicht auf dem letzten Stand (z.B. Description.txt ist ja jetzt module.json usw).

Damit komm ich schon noch zurecht (kann ja Code lesen und die mitgelieferten Plugins liefern ja guten Content).

Aber bei der Beschreibung zu Migrations steht zwar wie man Migrations erstellt, aber nicht, was man dazu vorher machen muss.

(Entwicklungsumgebung ist VS2022, mein Test-Publish ist eine Ubuntu-Server VM)

 

 

Wenn ich eine Migration starten will bekomm ich das hier:

Autofac.Core.DependencyResolutionException: An exception was thrown while activating λ:Microsoft.EntityFrameworkCore.DbContextOptions[] -> λ:Microsoft.EntityFrameworkCore.DbContextOptions -> λ:Microsoft.EntityFrameworkCore.DbContextOptions`1[[Smartstore.Core.Data.SmartDbContext, Smartstore.Core, Version=5.0.1.0, Culture=neutral, PublicKeyToken=null]].
 ---> System.ArgumentNullException: Value cannot be null. (Parameter 'context')
   at Autofac.ResolutionExtensions.ResolveOptionalService(IComponentContext context, Service service, IEnumerable`1 parameters)
   at Autofac.ResolutionExtensions.ResolveOptional[TService](IComponentContext context, IEnumerable`1 parameters)
   at Autofac.ResolutionExtensions.ResolveOptional[TService](IComponentContext context)
   at Smartstore.Data.Providers.DbFactoryOptionsExtension..ctor(DbContextOptions options) in F:\Source\Smartstore\src\Smartstore\Data\Providers\Bootstrapping\DbFactoryOptionsExtension.cs:line 20
   at Smartstore.Data.Providers.DbFactoryDbContextOptionsExtensions.UseDbFactory(DbContextOptionsBuilder optionsBuilder, DbFactory factory, String connectionString, Action`1 optionsAction) in F:\Source\Smartstore\src\Smartstore\Data\Providers\Bootstrapping\DbFactoryDbContextOptionsExtensions.cs:line 59
   at Smartstore.Data.Providers.DbFactoryDbContextOptionsExtensions.UseDbFactory(DbContextOptionsBuilder optionsBuilder, Action`1 optionsAction) in F:\Source\Smartstore\src\Smartstore\Data\Providers\Bootstrapping\DbFactoryDbContextOptionsExtensions.cs:line 33
   at Smartstore.Core.Bootstrapping.CoreStarter.<>c__DisplayClass2_0.<ConfigureServices>b__1(IServiceProvider c, DbContextOptionsBuilder builder) in F:\Source\Smartstore\src\Smartstore.Core\CoreStarter.cs:line 81
   at Microsoft.Extensions.DependencyInjection.EntityFrameworkServiceCollectionExtensions.<>c__DisplayClass6_0`1.<AddPoolingOptions>b__0(IServiceProvider sp, DbContextOptionsBuilder ob)
   at Microsoft.Extensions.DependencyInjection.EntityFrameworkServiceCollectionExtensions.CreateDbContextOptions[TContext](IServiceProvider applicationServiceProvider, Action`2 optionsAction)
   at Microsoft.Extensions.DependencyInjection.EntityFrameworkServiceCollectionExtensions.<>c__DisplayClass17_0`1.<AddCoreServices>b__0(IServiceProvider p)
   at Autofac.Extensions.DependencyInjection.AutofacRegistration.<>c__DisplayClass3_0.<Register>b__0(IComponentContext context, IEnumerable`1 parameters)
   at Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)
   at Autofac.Core.Activators.Delegate.DelegateActivator.<ConfigurePipeline>b__2_0(ResolveRequestContext ctxt, Action`1 next)
   at Autofac.Core.Resolving.Middleware.DelegateMiddleware.Execute(ResolveRequestContext context, Action`1 next)
   at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
   at Autofac.Core.Resolving.Middleware.DisposalTrackingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
   at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
   at Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
   --- End of inner exception stack trace ---
   at Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
   at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
   at Smartstore.Core.Bootstrapping.AutofacSerilogMiddleware.Execute(ResolveRequestContext context, Action`1 next) in F:\Source\Smartstore\src\Smartstore.Core\Platform\Logging\Bootstrapping\AutofacSerilogMiddleware.cs:line 32
   at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
   at Autofac.Core.Pipeline.ResolvePipeline.Invoke(ResolveRequestContext ctxt)
   at Autofac.Core.Resolving.Middleware.RegistrationPipelineInvokeMiddleware.Execute(ResolveRequestContext context, Action`1 next)
   at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
   at Autofac.Core.Resolving.Middleware.SharingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
   at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
   at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
   at Autofac.Core.Resolving.Middleware.CircularDependencyDetectorMiddleware.Execute(ResolveRequestContext context, Action`1 next)
   at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
   at Autofac.Core.Pipeline.ResolvePipeline.Invoke(ResolveRequestContext ctxt)
   at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, ResolveRequest request)
   at Autofac.Core.Resolving.ResolveOperation.ExecuteOperation(ResolveRequest request)
   at Autofac.Core.Resolving.ResolveOperation.Execute(ResolveRequest request)
   at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(ResolveRequest request)
   at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance)
   at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters)
   at Autofac.ResolutionExtensions.Resolve(IComponentContext context, Type serviceType, IEnumerable`1 parameters)
   at Autofac.ResolutionExtensions.Resolve(IComponentContext context, Type serviceType)
   at Autofac.Extensions.DependencyInjection.AutofacServiceProvider.GetRequiredService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetServices[T](IServiceProvider provider)
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.FindContextTypes()
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.FindContextType(String name)
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType, String namespace)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType, String namespace)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
An exception was thrown while activating λ:Microsoft.EntityFrameworkCore.DbContextOptions[] -> λ:Microsoft.EntityFrameworkCore.DbContextOptions -> λ:Microsoft.EntityFrameworkCore.DbContextOptions`1[[Smartstore.Core.Data.SmartDbContext, Smartstore.Core, Version=5.0.1.0, Culture=neutral, PublicKeyToken=null]].

Der Grund dafür ist mir auch klar, er hat keinen Connectionstring, von daher kann auch kein Vergleich zur bestehenden (lokalen) DB gemacht werden.

Die Dokumentation will hier, dass ich BuildConf EFMigrations nehme (die es aber nicht gibt).

Siehe https://smartstore.a...work Migrations.

 

 

Hier also meine Frage: 

Wie bekomme ich den Connection-String in den build-Prozess, damit ich Add-Migration / Update-Database laufen lassen kann?

 

Mir wären da 2 Szenarien wichtig, Migration im Plugin (bevorzugt) aber auch (falls alle Stricke reissen) im Smartstore selbst.

 

 

 

MfG

 

Chris

 



#2 Marcus Gesing

Marcus Gesing

    SmartStore AG

  • Administrators
  • 3831 Beiträge

Geschrieben: 28 December 2022 - 11:26   Best Answer

In Smartstore 5 wird für Datenbank-Migrationen Fluent Migrator verwendet (nicht mehr Entity Framework Migrations).
 
Im DevTools Modul sind einige auskommentierte Beispiele zu sehen.
 
Das GoogleMerchantCenter Modul verwendet ebf. eine Migration, um zusätzliche Produktdaten in einer eigenen Datenbanktabelle zu speichern. Voraussetzungen, damit das gelingt, kann man sich dort abgucken. Dazu zählt vor allem die IDbContextConfigurationSource Implementierung.
 
Die Smartstore 5 Entwickler-Dokumentation befindet sich hier (noch unvollständig), z.B. Module, Creating a Domain entity. Ich hoffe, dass hilft erstmal weiter.

  • stefanmueller und Algorithman gefällt das

Marcus Gesing

Smartstore AG


#3 Algorithman

Algorithman

    Advanced Member

  • Members
  • PunktPunktPunkt
  • 39 Beiträge

Geschrieben: 28 December 2022 - 11:42

Ja, danke, für die Links, das hilft. :)



#4 Algorithman

Algorithman

    Advanced Member

  • Members
  • PunktPunktPunkt
  • 39 Beiträge

Geschrieben: 28 December 2022 - 11:44

Eine Frage noch, gibts vielleicht ein Repo für ein leeres Plugin irgendwo?



#5 Marcus Gesing

Marcus Gesing

    SmartStore AG

  • Administrators
  • 3831 Beiträge

Geschrieben: 28 December 2022 - 20:13

Nein, im Moment nicht.


  • stefanmueller gefällt das

Marcus Gesing

Smartstore AG


#6 Algorithman

Algorithman

    Advanced Member

  • Members
  • PunktPunktPunkt
  • 39 Beiträge

Geschrieben: 28 December 2022 - 23:22

Zwei Sachen sind mir noch aufgefallen nachdem ich tiefer in den Source reingeschaut hab:

 

1. Das Modules Verzeichnis ist nach einem Clean nicht immer clean.

Einfacher Fix: 

    <Target Name="RemoveModules" AfterTargets="AfterClean;BeforeRebuild">
        <RemoveDir Directories="$(SolutionDir)src\Smartstore.Web\Modules" />
    </Target>

im Smartstore.Web project. Ansonsten kann es sein, dass da noch alte dll's rumlungern (z.B. nach Umbenennung eines Plugins oder Änderung des OutputFolders).

 

2. Es sind noch sehr viele magic strings im Source
z.B. bei Url.Action aufrufen sind nur teilweise nameof's verwendet (und da auch nicht immer auf die richtige Klasse verweisend). Für die Aufrufe kann man sich recht einfach einen Roslyn Analyzer schreiben, der einen dann warnt, wenn da ein String literal drin steht/nameof nicht auf den anderen Controller verweist).

Auch so bei den Controller Namen, Roslyn code generator kann einem da die Arbeit abnehmen und ein Snippet automatisch erstellen (z.B. Liste mit const strings), damit man da auch von den string literalen weg kommt.

zusätzlicher Vorteil: Man kann das System dann auch für die Plugins verwenden

 

So, für heut ist aber Schluss, wünsche noch einen schönen Abend :)




Auch markiert mit einem oder mehrerer dieser Schlüsselwörter: plugin, migration