Preferred way to use EF Core in Umbraco 13+?
# help-with-umbraco
d
I've started a project with Umbraco and EF Core in Umbraco 13. Getting it running and doing my first query was (somewhat) easy, but now I'm curious how everybody applies it in practice. Do you take the dependency on
IEFCoreScopeProvider
in the controller or do you hide it behind a repository/store? Do you abstract it in some way so you can unit test your business logic without a dependency on the database context class? I'll share my current approach (which I'm not totally sold on yet) in a response
I have these objects at the moment: - controller - "requesthandler" / "business logic" - store - projections For example:
Copy code
csharp
public BookController(BookRequestHandler requestHandler) : ControllerBase
{
    public async Task<IActionResult> GetBook(int bookId)
    {
        var model = await requestHandler.GetBook(bookId);
        return model is not null ? Ok(model)
            : NotFound();
    }
}
request handler:
Copy code
csharp
public class BookRequestHandler(IBookStore store)
{
    public async Task<BookViewModel> GetBook(int id)
    {
        var dbModel = await store.GetById(id, Projections.BookDetailModel);
        return dbModel.ToBookViewModel();
    }
}
store
Copy code
csharp
public class BookStore(IEFCoreScopeProvider<BookStoreContext> scopeProvider)
{
    public async Task<T> GetById<T>(int id, Func<IQueryable<BookDTO>, IQueryable<T>> projection)
    {
        using var scope = scopeProvider.CreateScope();
        var result = await scope.ExecuteWithContextAsync(context =>
        {
            var q = context.Books.Where(e => e.Id == id);
            return projection(q).FirstOrDefaultAsync();
        });
        scope.Complete();
        return result;
    }
}
Finally, a projection class:
Copy code
csharp
public static class Projections
{
    public static IQueryable<BookDetailProjection> BookDetailModel(IQueryable<BookDTO> query)
        => query.AsNoTracking()
        .Select(e => new BookDetailModel(e.Id, e.Title, e.Description));
}
Especially, I notice that it gets rather messy in the business logic layer if I need more specialized data. The amount of models grows quite large quite quickly and for every condition, I need to create more methods on my store and it all gets out of hand quite quickly in my opinion.
So, what does it look like for all of you?
k
What's the relation between Umbraco, Umbraco data and your EF'd data?
d
Well, I use Umbraco's notification publishing/handling on the scope to update custom data in the external index for example. I may reference an Umbraco node id here and there perhaps. Beyond that, I'm just following the docs, assuming that that's the way I should use it: https://docs.umbraco.com/umbraco-cms/13.latest/tutorials/getting-started-with-entity-framework-core#going-further
k
I was more interested in the interplay between Umbraco and its data and your own database. For example, sometimes we have existing applications with their own databases that we need to access from the Umbraco solution, but there's no real data relation; Umbaco doesn't know about the external data and vice versa. Sometimes we have data in a database that needs projecting into Umbraco (as nodes, or properties on nodes) but the custom database is the authority. I think the scenario makes a difference on how much you control you want to give the
IEFCoreScopeProvider
.
d
I'd say for 95% my custom tables are completely separate from Umbraco. I'll likely only be referencing back and forth here and there. So a custom table may be the datasource for a property in Umbraco.
10 Views