2016-09-03 2 views
1

У меня возникли проблемы с решением проблемы в моей общей реализации.Как обернуть DbSet.Include в моем собственном общем интерфейсе/классе

Прежде всего, то, что я пытаюсь выполнить

Я пытаюсь реализовать свой собственный репозиторий (а позже мой UOW), потому что это Я:

This classes, see the diagram

Так в чем проблема?

в моем IRepository Я это:

public interface IRepository<T> where T : class 
{ 
    List<T> GetAll(); 
    /* some other methods*/ 

    //Here is my problem 
    DbQuery<T> Include<T, U>(Expression<Func<T, U>> path); 
} 

и в моем классе у меня есть это:

public class Repository<T> : IRepository<T> where T : class 
{ 
    protected readonly MyDBContext context = null; 

    protected DbSet<T> DbSet { get; set; } 

    #region Constructors 
     public Repository() 
     { 
      context = new MyDBContext(); 
      DbSet = context.Set<T>(); 
     } 

     public Repository(MyDBContext context) 
     { 
      this.context = context; 
     } 
    #endregion 

    public List<T> GetAll() 
    { 
     return DbSet.ToList(); 
    } 

    /* more code for the rest of methods*/ 

    //And here is my problem 
    DbQuery<T> Include<T, U>(Expression<Func<T, U>> path) where U : class 
    { 
     return (DbSet<T>)DbSet.Include(path); 
    } 
} 

Итак, я судимое определить этот метод по-разному в интерфейсе но тот, который я использую, по-видимому, - по крайней мере, тот, который правильно определяет метод. Но в реализации у меня ошибка:

«Лучший перегрузки совпадение имеют некоторые недопустимые аргументы»

Я судимый извлекая Т, U в определении метода

DbQuery<T> Include(Expression<Func<T, U>> path) 

, но тогда я не могу указать U и у меня есть ошибка:

«Не можете найти тип или пространство имен для U, вы не указали директиву?"

Если я это сделать:

DbQuery<T> Include(Expression<Func<T, T>> path) 

У меня нет какой-либо ошибки, но не попадает в точку, чтобы использовать лямбда с различными классами

У меня также были ошибки, как T такое же во внутреннем и внешнем определении

идея позже в этом хранилище должно быть использовано для определения MyRepository как:

public class MyClassRepository : Repository<MyClass>, IMyClassRepository 

, а затем будет использоваться в контроллере, как:

MyClassRepository repo = new MyClassRepository(); 

, а затем:

repo.Include(o => o.MyOtherClass); 

На данный момент я решил это, определяя другой метод в интерфейсе

IQueryable<T> Include(string path) 

и реализован как:

public IQueryable<T> Include(string path) 
{ 
    return DbSet.Include(path); 
} 

, но затем в моем контроллере Я использовать так:

repo.Include("MyOtherClass"); 

, которая не ужасно, но я теряю способность лямбды.

Так что, если кто-то видит то, что мне не хватает, я буду очень благодарен.

Спасибо всем

Габриэль

ответ

1

Удалить общую декларацию T от метода Include, потому что вы уже определили его на уровне класса.

DbQuery<T> Include<U>(Expression<Func<T, U>> path); 

Не забудьте сделать метод общественности в реализации и устранить U ограничений, так как они не отображаются в интерфейсе.


В качестве примечания IDbSet уже является хранилищем и DbContext уже является UOW. IDbSet заставляет вас думать, что вы работаете с коллекцией объектов в памяти, а DbContext отслеживает изменения, внесенные в его IDbSets, и дает вам способ совершить эти изменения, когда вы закончите.

+0

Адриан, большое вам спасибо, иногда перед вами большой серый слон, и вы не можете его увидеть! Я уже реализовал и работает как шарм. – Gabriel

+0

Отлично. Вы не должны создавать DbContext в классах repo, а передавать его через конструктор, чтобы вы могли правильно реализовать UoW. –

+0

@AdrianIftode, о чем я хочу реализовать, включает в себя как «i => i.NavigationProperty», а не как путь строк? –

Смежные вопросы