2

I have many different Model types, each with their own context. Is there a built in mechanism to get the Models context without explicitly writing a getter/helper method? I.e. is there a way to link the context with the Model itself and then have a built in method to fetch the context.

Trying to reduce the redundant code I have to write without writing something generic and unsafe, like based on class names (strings) or something.

Thanks

EDIT:

I have many classes like this:

public class CatContext : DbContext
{
    public DbSet<Cat> Cat{ get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite("Data Source=animals.sqlite");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Cat>();
    }
}

public class Cat
{
    public string name { get; set; }
}

I want to write something generic, like:

public static void AddModel<T>(List<T> entries)
{
    // TODO: Get the context for the type T
    using (var context = GetModelContext<T>())
    {
        // do something generic, e.g. add them to the DB
    }
}

But I dont want to have write a method to fetch the context in a generic way. The models aren't always related to each other either.

7
  • 1
    "I have many different Model types, each with their own context' Why? Do you mean that you want the context tracking a particular entity instance, or a new context for a given entity type? Commented Sep 20, 2017 at 15:49
  • @DavidBrowne-Microsoft, do I have to define a context for each model? I updated my questions with some details of my setup. Commented Sep 20, 2017 at 16:33
  • @DavidBrowne-Microsoft, do I just do this: entityframeworktutorial.net/EntityFramework4.3/… Commented Sep 20, 2017 at 16:42
  • 1
    "One DbContext? Not one for each model" Yes. You may have multiple DbContexts if you have multiple repositories. But typically all your entities are saved to a single repository through a single DbContext type. Commented Sep 20, 2017 at 16:46
  • 1
    "does that have any performance issues" There's some startup cost that is per Entity, so if you have hundreds of entities you may want to divide. Also ASP.NET Core has DbContext pooling. Commented Sep 20, 2017 at 17:09

1 Answer 1

2

Not sure why you would want to do this, but the only way I could think to make something like this work is with a factory and probably reflection. IDbContextFactory. It would have to return a generic DbContext and the factory would need to know all of the possible DbContexts type to scan through. When given the model type, you'd have to go through that list and see if you could find a generic db set that implements that type. If yes, you'd have to use reflection to instantiate a new instance of that DbContext, cast it to DbContext and return it. If you didn't use reflection, you'd have to build that mapping by hand via types. Or, you'd have to build up a dictionary of ModelType (key) and DbContext type. Either way, I think you'd have to use reflection unless you want to manually wire that check up yourself in the factory directly.

Example Code:

public class DbContextFactory : IDbContextFactory
{
   private List<Type> _contextTypes = new List<Type>{ typeof(CatContext), etc };
   public DbContext GetContext<T>() 
   {
      foreach (var t in _contextTypes)
      {
         var props = t.GetProperties();
         foreach (var prop in props) 
         {
             //pseudo code
             if (prop.PropertyType is DbSet<> && prop.GetGenericTypes()[0] == typeof(T)) 
             {
                 return Activator.CreateInstance(t) as DbContext;
             }

         }
      }
      return null;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

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.