2010-06-30 4 views
2

Я пытаюсь написать общий репозиторий для моего приложения на основе Entity Framework. Вот мой прототип код:Создайте общий репозиторий для приложения Entity Framework

Интерфейс

public interface IDomainRepository 
    { 
     T GetById<T>(int id, Expression<Action<T>> idx) 
    } 

и репозиторий:

public class DomainRepository : IDomainRepository 
    { 
     private readonly DatabaseDataContext _ctx; 

     public DomainRepository(DatabaseDataContext ctx) 
     { 
      _ctx = ctx; 
     } 

     public T GetById<T>(int id, Expression<Action<T>> idx) 
     { 
      return _ctx.GetTable(typeof (T)).SingleOrDefault(idx); 
     } 
    } 

Выше тестовый код, который не работает. Но то, что я хотел бы быть в состоянии сделать это:

var repository = new DomainRepository(myContext); 

var client = repository.GetById<tbl_Clients>(23, c => c.clientId); 

Поэтому в основном я хочу, чтобы получить клиентский объект из базы данных, передавая в ИО плюс лямбда говорил GetById, что колонка идентификатор. Кроме того, я понятия не имею, как выполнить lambda с использованием пройденного id.

Может кто-нибудь помочь мне с этим?

EDIT:

Я действительно рядом. Я изменил GetById:

public T GetById<T>(int id, Expression<Func<T, object>> idx) 

и теперь я могу назвать это так:

var g = repository.GetById<tbl_Client>(23, c => c.cl_id); 

, но я не знаю, как использовать IDX и проверить его значение на пройденный ID:

public T GetById<T>(int id, Expression<Func<T, object>> idx) 
     { 
      //var col = idx.Compile().Invoke(T); 
      // How do I check if the column passed to "idx" is equal to id? 

      return default(T); 
     } 

EDIT: Думаю, что я получил эту работу сейчас. Вот мой весь код плюс тест:

public interface IDomainRepository 
    { 
     T GetById<T>(int id, Expression<Func<T, object>> idx) where T : class; 

     IEnumerable<T> GetAll<T>() where T : class; 
     IEnumerable<T> Query<T>(Expression<Func<T, bool>> filter) where T : class; 
     IEnumerable<T> Query<T>(ISpecification<T> filter) where T : class; 

     void Add<T>(T entity) where T : class; 
     void Delete<T>(T entity) where T : class; 
     Table<T> GetTable<T>() where T : class; 
    } 

public class DomainRepository : IDomainRepository 
    { 
     private readonly DatabaseDataContext _ctx; 

     public DomainRepository(DatabaseDataContext ctx) 
     { 
      _ctx = ctx; 
     } 

     public T GetById<T>(int id, Expression<Func<T, object>> idx) where T : class 
     { 
      return (from i in GetAll<T>() 
        let h = idx.Compile().Invoke(i) 
        where Convert.ToInt32(h) == id 
        select i).SingleOrDefault(); 
     } 

     public IEnumerable<T> GetAll<T>() where T : class 
     { 
      return GetTable<T>().ToList(); 
     } 

     public IEnumerable<T> Query<T>(Expression<Func<T, bool>> filter) where T : class 
     { 
      return GetTable<T>().Where(filter); 
     } 

     public IEnumerable<T> Query<T> (ISpecification<T> filter) where T : class 
     { 
      return GetTable<T>().Where(filter.Predicate); 
     } 

     public void Add<T> (T entity) where T : class 
     { 
      GetTable<T>().InsertOnSubmit(entity); 
     } 

     public void Delete<T> (T entity) where T : class 
     { 
      GetTable<T>().DeleteOnSubmit(entity); 
     } 

     public Table<T> GetTable<T>() where T : class 
     { 
      return _ctx.GetTable(typeof(T)) as Table<T>; 
     } 
    } 


var repository = new DomainRepository(_ctx); 

var g = repository.GetById<tbl_Client>(1, c => c.cl_id); 

Я буду проверять это, чтобы убедиться, что все в порядке.

Cheers. Jas.

ответ

0

Хорошо, я думаю, что у меня есть окончательный вариант, потребуется немного больше тестирования, хотя:

public T GetById<T>(int id, Func<T, int> idx) where T : class 
     { 
      return (from i in GetAll<T>() 
        where idx(i) == id 
        select i).SingleOrDefault(); 
     } 
+0

Проверьте SQL, сгенерированный этим методом. Насколько я понимаю, это может привести к материализации всей таблицы и применению Linq к объектам. –

-1

Вы можете просто разоблачить IQueryable через слои.

IQueryable пользователи {получить;}

Так что вы можете сделать что-то подобное в вашем коде Ui:

BLLContext.Users.Where (с => c.Username == "Foo");

BLLContext будет иметь базовый контекст DAL, который предоставляет IQueryable.

+1

Спасибо за ваше предложение, но я хочу хранилище, чтобы быть универсальным, таким образом, он не может знать о " Пользователи "в конкретном виде. Привет, в любом случае. –

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