【问题标题】:Implementing generic methods for a repository using Entity Framework code first首先使用实体​​框架代码为存储库实现通用方法
【发布时间】:2011-11-23 08:59:26
【问题描述】:

我正在使用Entity Framework 4.1repository pattern

我正在尝试创建将在大多数情况下使用的方法。我正在尝试创建一种方法来带回记录并根据提供的订单条件对其进行排序。它可以按 1、2 或 3 列排序。我希望指定这一点。我在Orchard framework找到了如下代码。

IRepository interface 中,它们具有以下内容(我省略了其他方法):

public interface IRepository<T>
{
     IEnumerable<T> Fetch(Expression<Func<T, bool>> predicate);
     IEnumerable<T> Fetch(Expression<Func<T, bool>> predicate, Action<Orderable<T>> order);
}

IEnumerable&lt;T&gt; Fetch(Expression&lt;Func&lt;T, bool&gt;&gt; predicate, Action&lt;Orderable&lt;T&gt;&gt; order); 的实现是:

public class Repository<T> : IRepository<T>
{
     public virtual IQueryable<T> Fetch(Expression<Func<T, bool>> predicate)
     {
          return Table.Where(predicate);
     }

     public virtual IQueryable<T> Fetch(Expression<Func<T, bool>> predicate, Action<Orderable<T>> order)
     {
          var orderable = new Orderable<T>(Fetch(predicate));
          order(orderable);
          return orderable.Queryable;
     }
}

Orderable class:

public class Orderable<T>
{
     private IQueryable<T> _queryable;

     public Orderable(IQueryable<T> enumerable)
     {
          _queryable = enumerable;
     }

     public IQueryable<T> Queryable
     {
          get { return _queryable; }
     }

     public Orderable<T> Asc<TKey>(Expression<Func<T, TKey>> keySelector)
     {
          _queryable = _queryable
               .OrderBy(keySelector);
          return this;
     }

     public Orderable<T> Asc<TKey1, TKey2>(Expression<Func<T, TKey1>> keySelector1,
          Expression<Func<T, TKey2>> keySelector2)
     {
          _queryable = _queryable
               .OrderBy(keySelector1)
               .OrderBy(keySelector2);
          return this;
     }

     public Orderable<T> Asc<TKey1, TKey2, TKey3>(Expression<Func<T, TKey1>> keySelector1,
          Expression<Func<T, TKey2>> keySelector2,
          Expression<Func<T, TKey3>> keySelector3)
     {
          _queryable = _queryable
               .OrderBy(keySelector1)
               .OrderBy(keySelector2)
               .OrderBy(keySelector3);
          return this;
     }

     public Orderable<T> Desc<TKey>(Expression<Func<T, TKey>> keySelector)
     {
          _queryable = _queryable
               .OrderByDescending(keySelector);
          return this;
     }

     public Orderable<T> Desc<TKey1, TKey2>(Expression<Func<T, TKey1>> keySelector1,
          Expression<Func<T, TKey2>> keySelector2)
     {
          _queryable = _queryable
               .OrderByDescending(keySelector1)
               .OrderByDescending(keySelector2);
          return this;
     }

     public Orderable<T> Desc<TKey1, TKey2, TKey3>(Expression<Func<T, TKey1>> keySelector1,
          Expression<Func<T, TKey2>> keySelector2,
          Expression<Func<T, TKey3>> keySelector3)
     {
          _queryable = _queryable
               .OrderByDescending(keySelector1)
               .OrderByDescending(keySelector2)
               .OrderByDescending(keySelector3);
          return this;
     }
}

所以可以使用的方式如下:

var foos = _fooRepos.Fetch(
     f => f.Name == "two" || f.Name == "three",
     o => o.Asc(f => f.Name, f => f.Id)
);

这是实现我想要实现的目标的最佳方式吗?我试图让它尽可能简单。如果有任何示例代码和文章,我将不胜感激。

【问题讨论】:

    标签: c# entity-framework c#-4.0 entity-framework-4 entity-framework-4.1


    【解决方案1】:

    我确信 Orchard 的人有他们的理由(没有查看代码库),但我只是想知道与更“标准”的基于 LINQ/IQueryable 的解决方案相比,它带来了什么?

    public interface IRepository<T>  
    {  
        IQueryable<T> All(); 
    } 
    

    用法:

    var foos = from f in _foosRepos.All()
               where f.Name == "two" || f.Name == "three"
               orderby f.Name, f.Id;
    

    var foos = _foosRepos.All()
            .Where(f => f.Name == "two" || f.Name == "three")
            .OrderBy(f => f.Name).ThenBy(f => f.Id);
    

    【讨论】:

    【解决方案2】:

    由于您提到项目可以按 1、2 或 3 个字段排序,您可以扩展 jeroenh 的响应,并将其与 Orchard 的逻辑“合并”:

    public interface IRepository<T>
    {
        IQueryable<T> All();
        IQueryable<T> Sorted(Func<T, object> sort1, Func<T, object> sort2 = null, Func<T, object> sort3 = null);
    }
    
    public class Repository<T> : IRepository<T>
    {
        public IQueryable<T> All()
        {
            // TODO: Implement real data retrieval
            return new List<T>().AsQueryable();
        }
    
        public IQueryable<T> Sorted(Func<T, object> sort1, Func<T, object> sort2 = null, Func<T, object> sort3 = null)
        {
            var list = All();
    
            var res = list.OrderBy(sort1);
            if (sort2 != null)
                res = res.ThenBy(sort2);
            if (sort3 != null)
                res = res.ThenBy(sort3);
            return res.AsQueryable();
        }
    }
    

    【讨论】:

    • 如果你想要高效的排序(在数据库中),你应该使用Expression&lt;Func&lt;&gt;&gt; 而不仅仅是Func&lt;&gt;
    【解决方案3】:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-03
      相关资源
      最近更新 更多