1

I'm using Autofac and EF6.

I have a service which I would like to use with dbContext or with local collection. I've already tried to use InMemoryDatabase and inject it in a service, but I need to load all related entites due to validation rules and it'll lead to performance issues.

Is any way to solve this issue without creating the same service, but for local store (in such way I'll need to edit the logic in both of them and can lead to different behaviour)?

The goal of this is to preload in some cases all data and use local store, accessing multiple times to db context cause low performance.

Example of service:

public class ProductServiceDb {
  private readonly IDbContext _db;

  public ProductServiceDb(IDbContext db) {
   _db = db;
  }

  public List<Product> GetAvailable()
  {
    return _db.Products.Where(_=>_.InStock).AsNoTracking().ToList();
  }
}

public class ProductServiceLocal {
  public List<Product> Products {get; set;}

  public List<Product> GetAvailable()
  {
    return Products.Where(_=>_.InStock).ToList();
  }
}

Also I've already thought about local data, but in such way I need to check in all methods if it's local data and use Local property then.

0

1 Answer 1

1

I once made this little extension method to tell EF that I'd prefer to get data from its cache:

public static IEnumerable<TEntity> PreferLocal<TEntity>(this DbSet<TEntity> dbSet, 
    Expression<Func<TEntity, bool>> predicate) where TEntity : class
{
    var func = predicate.Compile();
    return dbSet.Local.Any(func) ? dbSet.Local.Where(func) : dbSet.Where(predicate);
}

As you see, if there's no data that meets the given predicate then EF tries to get it from the database.

I use this function in more complex business logic when I know that some entities will have to be addressed more than once, while it's not always clear when they will be fetched for the first time.

A caveat: it works well the way I use it, but it may fail badly if you rely on navigation properties being populated fully. When, for example, you first fetch a couple of products based on some predicate and then order lines, not all order lines may have a orderLine.Product property populated. Also, if lazy loading is enabled, EF will still query the database when collection navigation properties are addressed.

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

6 Comments

Thank you, intersting solution, but it makes all queries sync as returns IEnumerable. Is any workaround to using it async way?
@user8388835 it's kinda frowned upon to keep moving the goal-post.
@Micky, instead of performance issue, it will lead to scalability problems, so such solutions are not acceptable for me and I'm asking for possible workarounds
Yeah, what @MickyD is saying, it's quite frustrating for answerers to see the target change after answering. Since I never post untested code and I don't have time to change & test this I suggest you try to modify it and feel free to post it or change my answer.
|

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.