Adapter pattern for IDbSet properties of a DbContext class
Asked Answered
C

1

2

Is there a way to use the method described in this answer No FindAsync() method on IDbSet for DbSet properties of a DbContext?

Edit:

The answer linked contains a description how to build a interface inheriting from IDbSet and adding support for the SearchAsync method of the DbSet class. I understand everything which Keith Payne has written, but I don’t know how I can use it in DbContext.

For example I’ve a DbContext which looks something like this:

public class MyContext : DbContext
{ 
    public DbSet<Customer> Customers { get; set; }
}

How can I use MyDbSet (class described in the answer.) or a similar class, instead of DbSet?

public class MyContext : DbContext
{ 
    public MyDbSet<Customer> Customers { get; set; }
}

The problem is now, that Entity Framework seem to generate only tables for properties of type IDbSet or DbSet.

Chipper answered 19/5, 2014 at 6:25 Comment(4)
Much, much better. However i think you second example is exactly what you are supposed to do. Are you having problems where doing that does not work? If so, can you explain what kind of problems you are having?Divorcee
I thought the same… but the second example doesn't work. Entity Framework generates no tables for properties which are not of type DbSet<T> or IDbSet<T>.Chipper
Then you should mention that in your question, its pretty relevent information. When you ask a question you should always try to show what you tried (you did that) and what results you got when you tried it (left that part out). Also be sure to include the new information in the question itself, not just the comments. People browsing on phones see a lot fewer comments by default than on the web, a few upvoted comments and your last reply would be in the "click to see more" screen. (Still a good question, I upvoted, I would answer too if I knew the answer)Divorcee
Thanks for your feedback… You're absolutely right I’ve added my “results” to the question.Chipper
L
0

You have regular DbSet on your context and create an adapter adding the requested interface.

public interface IAsyncDbSet<T> : IDbSet<T>
    where T : class
{
    Task<T> FindAsync(params Object[] keyValues);
}

public sealed class DbSetAdapter<T> : IAsyncDbSet<T>, IDbSet<T>
    where T : class
{
    private readonly DbSet<T> _innerDbSet;

    public DbSetAdapter(DbSet<T> innerDbSet)
    {
        _innerDbSet = innerDbSet;
    }

   public Task<T> FindAsync(params object[] keyValues)
   {
          return _innerDbSet.FindAsync(keyValues);
   }

   //Here implement each method so they call _innerDbSet like I did for FindAsync
}

Now you can create a DbSetAdapater when you need it and get an IAsyncDbSet. You could duplicate your properties as EF seems to ignore them or add an ToAsyncDbSet() extension method to IDbSet<T>

public class MyContext : DbContext
{ 
    public DbSet<Customer> Customers { get; set; }
    public IAsyncDbSet<Customer> CustomersAsync { get { return new DbSetAdapter<Customer>(Customers); } }
}
Lordling answered 22/8, 2014 at 9:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.