UI Builder with repository to an external table
# help-with-umbraco
a
Hi everyone, We need to use UI Builder to manage some data held in a separate database and, because of the slightly complex nature of the data we need to save/load, we're using a repository as described here: https://docs.umbraco.com/umbraco-ui-builder/v/13.ui-builder.latest-lts/advanced/repositories From there, we stubbed out our tree with some noddy data just to get it visible and we get an error that the table name doesn't exist (
Invalid object name 'Company'.
is the precise error message). After digging around, I can see that the scope provider that gets injected into our repository is pointing to the default Umbraco connection string even though we set the correct connection string in the application startup:
Copy code
services.AddUmbracoDbContext<CustomDBContext>(options =>
            {
                options.UseSqlServer("name=ConnectionStrings:CustomDB");
            });
I'm at a bit of a loss as to why this would be the case. Does anyone have any ideas? Thanks
p
@Matt Brailsford we're raising a support ticket now, that'll come to you but heads up this is the thread I was just talking about
m
What is
AddUmbracoDbContext
? This doesn't look standard. And I guess the scope provider using the default umbraco connection string is correct because it knows nothing about EFCore so when implementing your repository, because your are bypassing the default logic, it's your responsibility to handle this. Might be worth trying the config option also to provide an alternative connection string https://docs.umbraco.com/umbraco-ui-builder/collections/the-basics#setconnectionstring-string-connectionstringname-collectionconfigbuilder-less-than-tentitytype-greate
p
Thanks Matt
a
Thanks for looking, @Matt Brailsford. I've taken the detail here, added it to a ticket and elaborated on the points you raised. You'll see it in the email, but to briefly answer your questions: *
AddUmbracoDbContext
is the way of adding an additional DB context that is suggested by the Umbraco documentation * Based on the UI Builder documentation, it looks like using
SetConnectionString
doesn't give us the overrides that repositories does and we need that to be able to save data in multiple places when saving our content.
a
Are you intending to use EFCore or NPoco? I've used UI Builder with both with EFCore dbcontext pointing to the main Umbraco db as well as using a completely separate database. You should be able to just inject your DbContext into the Ui Builder Repository and away you go. If you can share a bit more info I can try and suggest some options.
a
Hi Andrew. Thank you for taking a look at this with me. Any insight you have would be very appreciated. Here's what we have so far: For context: We need to update data across multiple tables on one page so, from my understanding, we need to use a repository to achieve this. We looked at the very useful guide on 24 days in Umbraco where this is done in Umbraco 12. The new context is added as shown in my original message and that gets hit. I've tried adding the connection string as shown as a pointer to a location in my appsettings and also as a hard-coded connection string. The problem is that when we get to the repository, we have something like this:
Copy code
public class CompanyUIBuilderRepository : Repository<Company, int>
    {
        private readonly IEFCoreScopeProvider<CustomDBContext> _scopeProvider;

        public CompanyUIBuilderRepository(RepositoryContext context, IEFCoreScopeProvider<CustomDBContext> scopeProvider) : base(context)
        {
            _scopeProvider = scopeProvider;
        }
    }
If I break things here and inspect
scopeProvider._scopeProvider.DatabaseFactory.ConnectionString
, it has the Umbraco DB connection string and not the one set in our startup.cs. This, I believe, is the reason that we get the error that the Company table doesn't exist - we're looking to the wrong DB and I don't know why.
m
So UI Builder is really only responsible for passing you the RepositoryContext any other args you request are just resolved from the DI container. We don't really have anything to do with the
IEFCoreScopeProvider
and how it's created so not sure how that has the wrong connection. If this is being provided by a CMS provided API, then I think is potentially more of a CMS issue, than a UI Builder issue. Maybe Andrew can provide details on how his repository is setup.
a
Thanks Matt - that's what we're thinking too at this point.
m
Ok, as you have a support ticket open, let me point them in that direction and see if they can get some assistance from the CMS team. In the meantime if Andrew gets time to share an example, maybe that can also shed some light.
p
a
Hi @Matt Brailsford. Sorry to tag you but Paul is away and he's asked me to keep on top of this. I was wondering if there's been an update? We last had communication from Dennis about 24 hours ago saying he'll speak to the CMS team but heard nothing since.
m
From what I can see it's been suggested it should be raised as a bug on the CMS project as it looks to be a fault with the Umbraco EF Core integration. As such the fix is out of my hands. You'd be best to move this to the CMS issue tracker and get further support there.
a
Hi @Alex Wilks - sorry for the silence - was off on holiday and just got back. The
IEFCoreScopeProvider
is a scope provider created by Umbraco to create new scopes for the Umbraco database tables using entity framework (instead of NPoco). You need to inject YOUR context (with the other connection string) into the Repository instead. Let me have a quick review of my classes and see what code snippets I can share.
Hi @Alex Wilks - here's a gist showing the bare bones setup. https://gist.github.com/andrewmckaskill/448cad9120e842a3425a255f66aac804 It's got the following components (which are borrowed from a working project, but anonymised in the browser - so may not compile directly): - Composer: options for configuring DbContext using existing umbraco connection string as well as option for configuring with completely independent connection string - Context: bare bones and standard - Repository: inject the context and use it to return entities. I have a better base UI builder repository that uses a model/entity mapper combo, but it's got lots of other dependancies. I'd like to turn it into a package, but it'll take a little bit more time. Let me know if that's enough to point you in the right direction or if you continue to have difficulties.
72 Views