为Entity Framework应用程序构建通用存储库

时间:2010-06-30 15:31:59

标签: .net entity-framework repository

我正在尝试为基于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);

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

有人可以帮我这个吗?

编辑:

我真的很亲密。我改变了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);
        }

编辑: 我想我现在有这个工作了。这是我的整个代码,加上测试:

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

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

干杯。 雅各

2 个答案:

答案 0 :(得分: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();
        }

答案 1 :(得分:-1)

您可以通过图层公开IQueryable。

IQueryable Users {get;}

所以你可以在你的ui代码中做这样的事情:

BLLContext.Users.Where(c =&gt; c.Username ==“foo”);

BLLContext将有一个潜在的DAL上下文,它暴露了IQueryable。