0

I have a .NET Core app using EF Core. I'm on .NET 8.

I have a bunch of independent contexts declared in C# and F#. The app doesn't know it but the same connection string is injected for all of them. As they all use a schema there are no conflicts and everything runs fine.

The problem arose when I wanted to try and use EnsureCreatedAsync instead of migrating the contexts in my tests.

Since all contexts share the same connection, I can only call EnsureCreatedAsync once. I cannot call it per context as the document is explicit: if there are any tables in the database then no action happens.

I managed to overcome that problem by defining a combined context like that:

public class CombinedDbContext : WriteContextBase
{
    private readonly IEnumerable<Action<ModelBuilder>> _onModelCreatings;

    public CombinedDbContext(DbContextOptions<CombinedDbContext> options, IEnumerable<Action<ModelBuilder>> onModelCreatings) : base(options, "none") => _onModelCreatings = onModelCreatings;

    protected override void OnModelCreating(ModelBuilder modelBuilder) => _onModelCreatings.ToList().ForEach(onModelCreating => onModelCreating(modelBuilder));
}

And here is how I use it:

async Task CreateDatabases(IHost host)
{
    aait using var scope = host.Services.CreateScope();
    var serviceProvider = scope.ServiceProvider;
    var contexts = serviceProvider.GetServices<IMigratableContext>().ToList();
    var onModelCreatings = contexts
            .Select(context => (Action<ModelBuilder>)context.OnModelCreating)
            .ToList();
    var combinedDbContext = ActivatorUtilities.CreateInstance<CombinedDbContext>(serviceProvider, onModelCreatings);
    await combinedDbContext.Database.EnsureCreatedAsync();
}

I notice that all C# tables are created but not the F# ones.

If I filter onModelCreatings to have only the F# contexts then the F# tables are created.

Does anyone have any idea to why?

5
  • If you want multiple DbContexts pointing at the same database, regardless of C# or F#, you need each to specify separate tracking tables. (See stackoverflow.com/questions/50527157/…) Commented Aug 22, 2024 at 20:49
  • Thank you but a) not true: been working this way for years b) irrelevant to the question Commented Aug 23, 2024 at 7:11
  • Ok, I see what you are doing, combining the DbContexts, I read that as being a work-around. It does look like that should work at least for C# DbContexts. I was curious about EF within F#, how does that even work? Within an F# library I wasn't even able to add any package for MS.EF.Core. The examples I have seen access a C# library. When you mention filtering the F# ones and it works (for the F#) where/how are you performing that filtering? I.e. when building the list of onModelCreating fn()s or when iterating through them? Commented Aug 23, 2024 at 9:40
  • 1) EF Core in F#: I just added the package and its works fine. Except the migrations that are done in a dedicated C# project for these F# contexts. Maybe linked to my pb. 2)Filtering: var contexts =... Where(getF#OnlyFilterByContextName)... Commented Aug 24, 2024 at 7:52
  • Hmm, it may help to make a minimal reproducible example, a small set of projects with 2 simple DbContexts in C# and F# then your CombinedDbContext structure. If that still reproduces the issue then you can get more eyes and debuggers on it, possibly assistance from the EF Core maintainers. If it works fine then you can expand it out based on how your specific implementation works to shed light on anything particular that might be tripping it up. Commented Aug 24, 2024 at 9:51

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.