Я пытаюсь написать общий репозиторий для моего приложения на основе 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.
Проверьте SQL, сгенерированный этим методом. Насколько я понимаю, это может привести к материализации всей таблицы и применению Linq к объектам. –