代码之家  ›  专栏  ›  技术社区  ›  Jason Evans

为实体框架应用程序构建通用存储库

  •  2
  • Jason Evans  · 技术社区  · 14 年前

    我正在尝试为基于实体框架的应用程序编写一个通用存储库。这是我的原型代码:

    界面

    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);
    

    所以基本上我想通过传入ID和lambda来从数据库中获取客户机实体 GetById ID列是什么。另外,我不知道如何使用传递的ID执行lambda。

    有人能帮我吗?

    编辑:

    我真的很亲近。我变了 盖比 :

    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);
            }
    

    编辑: 我想我现在可以工作了。这是我的全部代码,加上测试:

    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);
    

    我会继续测试这个看看是否可以。

    干杯。 JAS。

    2 回复  |  直到 13 年前
        1
  •  0
  •   Tim Cooper    13 年前

    好吧,我想我已经有了最终版本,不过需要更多的测试:

    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();
            }
    
        2
  •  -1
  •   Matteo Mosca    14 年前

    你可以通过层层曝光iqueryable。

    iQueryable用户获取;

    因此,您可以在UI代码中执行类似的操作:

    bllcontext.users.where(c=>c.username==“foo”);

    bllcontext将有一个底层DAL上下文,该上下文公开iQuery。