0

I wanted to try to expose a DbContext instance through a get statement:

public class SomeContext : DbContext
{
    public SomeContext()
    {

    }

    public DbSet<SomeModel1> SomeModel1s { get; set; }
    public DbSet<SomeModel2> SomeModel2s { get; set; }

   //etc
}

public class SomeInterfaceImplementation
{
    SomeContext ContextInstance { get; }
    //etc
}

But instead of using ContextInstance as a singleton, I want to do something so that calling ContextInstance actually does something like:

someVar = ContextInstance.SomeModel1s.Where(x => x.SomeID == externalID).OrderBy(x => x.SomeProperty).ToList();
//becomes the same as
using (var db = new SomeContext())
{
  someVar = db.SomeModel1s.Where(x => x.SomeID == externalID).OrderBy(x => x.SomeProperty).ToList();
}

basically, I just want to hide the using statement and create and dispose an instance of SomeContext every time ContextInstance is called. Hopefully I make sense. Does anyone have something in mind to do this?

2
  • What kind of application framework are you using? Asp.net core or? Commented Sep 9, 2016 at 6:05
  • @DannyChen I'm using this for UWP Commented Sep 9, 2016 at 6:07

1 Answer 1

1

This may not be a very good idea, because there are some standard scenarios with DbContext. For example DbContext implements Unit of Work pattern so the using may be necessary.

But you can make what you want although is't not easy.

You need implement IQueryProvider<TEntity> interface and especially the generic method Execute:

public class EFDbSetProvider<TEntity> : IQueryableProvider<TEntity>
where TEntity : class
{
    public TResult Execute<TResult>(Expression expression)
    {
        using (dbContext = new DbContext())
        {
             return (TResult) dbContext.Set<TEntity>.Provider.Execute(expression);
        }
    }
}

Also you'll need implement corresponding IQueryable<TEntity> interface, but as I can see this implementation should be very simple.

public class EFQueryable<TEntity> : IQueryable<TEntity>
{
    . . .
}

public static class SomeContext
{
    public static EFQueryable<SomeModel1> SomeModels1 { get; set; }
    public static EFQueryable<SomeModel2> SomeModels2 { get; set; }
}

someVar = SomeContext.SomeModel1s.Where(x => x.SomeID == externalID).OrderBy(x => x.SomeProperty).ToList();

The Execute method will be called from ToList, then it will create DbContext and pass the assemblied expression to DbSet<TEntity>.Provider.Execute.

You may google "custom LINQ providers" or "IQueryable implementation example". F.e. I found the article Implementing a ustom LINQ provider so you can start here for details.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, I'm going to look into this

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.