Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Anders Brännmark 228 posts 280 karma points
    Sep 12, 2023 @ 15:11
    Anders Brännmark
    0

    Entity Framework in Umbraco 12 and custom tables in a separate logic project

    Trying to wire up to use Entity Framework with Umbraco EFCoreContext in a separate logic project but can seam to getting working. Anyone done this before?

    Seen this but when having a separate project, that isnt running the "Umbraco"? https://docs.umbraco.com/umbraco-cms/tutorials/getting-started-with-entity-framework-core

  • Mark Jarvis 5 posts 116 karma points
    Sep 12, 2023 @ 16:08
    Mark Jarvis
    0

    Hello Anders,

    I've been working recently on a similar project. I found this article by Jon Jones extremely helpful;

    https://www.jondjones.com/learn-umbraco-cms/umbraco-12-tutorials/how-to/custom-database-tables-with-umbraco-12-and-entity-framework-deep-dive/

    The biggest issue I ran into was the using statement for IEFCoreScope in the controller.

    Instead of this type of declaration:
    using IEfCoreScope<MyContext> scope = _efCoreScopeProvider.CreateScope();
    
    I had to use the traditional type:
    using IEfCoreScope<MyContext> scope = _efCoreScopeProvider.CreateScope() {
     //Do DbContext things
    }
    

    Aside from that I setup a traditional Api to grab third party data and import it to the database.

    If you have any specific questions, I'd be glad help also, since it is fresh in my mind.

    Have a great day, --Mark

  • Anders Brännmark 228 posts 280 karma points
    Sep 13, 2023 @ 06:16
    Anders Brännmark
    0

    Hi,

    Did you run this in a separate project from the "umbraco" web project?

    Can seam to wire up the dbcontext in the separate project any other way than with EF standard way.

    builder.Services.AddDbContext<CommerceContext>(options => options.UseSqlServer(_config.GetConnectionString("umbracoDbDSN"));
    //builder.Services.AddUmbracoEFCoreContext<CommerceContext>(_config.GetConnectionString("umbracoDbDSN"), _config.GetConnectionStringProviderName("umbracoDbDSN"));
    

    As the AddUmbracoEFCoreContext needs AddUmbraco before and that seams wrong in this case to add Umbraco with all whistles and bells? Or maybe it should add a slimed down version of the AddUmbraco statement? Anyone have a "core" AddUmbraco setup that one is supposed to use instead?

  • Anders Brännmark 228 posts 280 karma points
    Sep 13, 2023 @ 10:10
    Anders Brännmark
    101

    Got it working so that migrations can be in the logic project now. Had to make a custom IDesignTimeDbContextFactory in the logic project that ef migrations use.

    public class CommerceDesignTimeContextFactory : IDesignTimeDbContextFactory<CommerceContext>
    {
        public CommerceContext CreateDbContext(string[] args)
        {
            var optionsBuilder = new DbContextOptionsBuilder<CommerceContext>();
            optionsBuilder.UseSqlServer();
            return new CommerceContext(optionsBuilder.Options);
        }
    }
    

    Wire up as recommended in the web project that references the separate project.

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddUmbraco(_env, _config)
            .AddBackOffice()
            .AddWebsite()
            .AddDeliveryApi()
            .AddComposers()
            .Build();
        services.AddUmbracoEFCoreContext<CommerceContext>(_config.GetConnectionString("umbracoDbDSN"), _config.GetConnectionStringProviderName("umbracoDbDSN"));
    }
    
  • Mark Jarvis 5 posts 116 karma points
    Sep 13, 2023 @ 15:05
    Mark Jarvis
    0

    Great! Glad you got it working. Yes that is a very similar approach that I took.

    I've built my migrations by hand and installed any required umbraco packages in the logic project to satisfy dependencies. As a temporary measure for testing I setup a pre-build script that copies AppCode/* and AppPlugins/* to the web project for execution and testing. Eventually I will roll that logic project into a nuget package and install it into my main site.

    --Mark

  • Peter Laurie 48 posts 122 karma points
    Dec 22, 2023 @ 01:32
    Peter Laurie
    0

    Hi, I have just upgraded to Umbraco 13 and the code is now telling me

    builder.Services.AddUmbracoEFCoreContext is obsolete.

    It reccomeds using:

    builder.Services.AddUmbracoDbContext

    But I cannot get this to work, I have tried the following - as an example:

    builder.Services.AddUmbracoDbContext<umbracoCmsDbContext>(options =>{`options.UseDatabaseProvider(builder.Configuration.GetConnectionStringProviderName("CMTCookies")!,
      builder.Configuration.GetConnectionString("CMTCookies")!);});
    

    The Umbraco documentation for Umbraco 13 has not been updated yet for this.

    This is the error:

    AggregateException: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Umbraco.Cms.Core.Events.INotificationAsyncHandler`1[Umbraco.Cms.Core.Notifications.UmbracoApplicationStartedNotification] Lifetime: Transient ImplementationType: CommercialTrust.Umbraco.EntitiyFrameworkContext.RunEFDBMigrations': Unable to resolve service for type 'CommercialTrust.Umbraco.EntitiyFrameworkContext.CMTProcessDbContext' while attempting to activate 'CommercialTrust.Umbraco.EntitiyFrameworkContext.RunEFDBMigrations'.)
    

    Any help would be appreciated.

    Thank you, Kind regards, Pete

  • Anders Brännmark 228 posts 280 karma points
    Dec 22, 2023 @ 07:16
    Anders Brännmark
    0

    Hi,

    I ended up doing like this in my Umbraco project, using a regular DbContext as you cant specify use sql server...:

    services.AddDbContext<MyContext>(options =>     
    {
        options.UseSqlServer(_config.GetConnectionString("umbracoDbDSN"));
    }
    

    In my logic project I wired up a designtimecontext so that I can run migrations also manually against the database:

    public class MyDesignTimeDbContextFactory : IDesignTimeDbContextFactory<MyContext>
    {
        public CommerceContext CreateDbContext(string[] args)
        {
            var optionsBuilder = new DbContextOptionsBuilder<MyContext>();
            optionsBuilder.UseSqlServer("Server=SERVER;Database=DATABASE;User Id=USER;Password=PASSWORD;TrustServerCertificate=true;");
            return new MyContext(optionsBuilder.Options);
        }
    }
    

    Going to move the settings out later from code but havent had the time yet. Not in production, only local still.

Please Sign in or register to post replies

Write your reply to:

Draft