我有一个抽象类来实现我的所有查询。我的Get功能是:
public virtual List<TEntity> Get(Expression<Func<TEntity, bool>> criteria)
{
return _dbSet.Where(criteria).OrderByDescending(OrderBy).ThenBy(ThenOrderBy).ToList();
}
ThenOrderBy属性为:
public virtual Func<TEntity, object> ThenOrderBy { get; set; }
OrderBy 属性是必需的,但我的新属性 ThenOrderBy 不是必需的,并且未在继承此抽象类的所有类中实现。
我收到此错误:
值不能为空
有没有办法保留这些干净的代码而不会放置“if's”的句子?
我使用的解决方案:
public virtual List<TEntity> Consultar(Expression<Func<TEntity, bool>> criteria)
{
var query = _dbSet.Where(criteria);
query = OrderDescending ?
query.OrderByDescending(OrderBy).AndOptionallyBy(ThenOrderBy)
:
query.OrderBy(OrderBy).AndOptionallyBy(ThenOrderBy);
query = (paggedSearch && Skip > 0) ? query.Skip(Skip) : query;
query = (paggedSearch && Take > 0) ? query.Take(Take) : query;
return query.ToList();
}
并创建了一个新的扩展类
public static class ExtensionMethods
{
public static IOrderedQueryable<TSource> AndOptionallyBy<TSource, TKey>(this IOrderedQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
{
return (keySelector == null) ? source : source.ThenBy(keySelector);
}
}
答案 0 :(得分:5)
不,你需要用if阻止它。但是,您可以在不访问数据库的情况下构建EF查询:
public virtual List<TEntity> Get(Expression<Func<TEntity, bool>> criteria)
{
var query = _dbSet.Where(criteria);
if(OrderBy != null)
{
query = query.OrderByDescending(OrderBy);
if(ThenOrderBy != null)
{
query = query.ThenBy(ThenOrderBy);
}
}
return query.ToList();
}
答案 1 :(得分:4)
如果短暂则:
public virtual List<TEntity> Get(Expression<Func<TEntity, bool>> criteria)
{
var result = _dbSet.Where(criteria).OrderByDescending(OrderBy);
if(ThenOrderBy != null)
{
result = result.ThenBy(ThenOrderBy);
}
return result.ToList();
}
答案 2 :(得分:3)
有时最干净的解决方案 使用一堆print_name
语句。在这种情况下,您可以检查if()
是否为空:
ThenOrderBy
当然,有很多方法可以滥用语法来压缩这段代码,但明确发生的事情会使代码更易于阅读,因此更加清晰。
答案 3 :(得分:3)
您可以创建自己的AndOptionallyBy
方法,如果提供了第二个条件,或者保留IOrderedQueryable,例如:
public static IOrderedQueryable<TSource> AndOptionallyBy<TSource, TKey>(
this IOrderedQueryable<TSource> source,
Expression<Func<TSource, TKey>> keySelector)
{
if (keySelector==null)
{
return source;
}
else
{
return source.ThenBy(keySelector);
}
}
我不会用这个。虽然这允许您使用函数链,但它会让代码的维护者感到惊讶。
一方面你有:
var result = _dbSet.Where(criteria)
.OrderByDescending(OrderBy)
.AndOptionallyBy(ThenOrderBy)
.ToList();
另一方
var query = _dbSet.Where(criteria)
.OrderByDescending(OrderBy);
if (ThenOrderBy!=null)
{
query = query.ThenBy(ThenOrderBy);
}
var result = query.ToList();
您认为哪个人对其他人更清楚?
<强>更新强>
使用条件创建分页查询很容易:
var query = _dbSet.Where(criteria);
var orderedQuery=OrderDescending
?query.OrderByDescending(OrderBy)
:query.OrderBy(OrderBy);
if (buscaPaginada)
{
if (Skip > 0)
{
query = query.Skip(Skip);
}
if (Take >0)
{
query = query.Skip(Skip);
}
}
return query.ToList();
答案 4 :(得分:1)
如果您希望ThenBy
具有默认行为,则只需将其默认为不会影响排序的内容而不是null
。例如entity => 1
我测试了它,如下所示,这使我无法设置OrderBy
或ThenOrderBy
,它仍然按预期工作:
public class TestClass<TEntity>
{
private IEnumerable<TEntity> data;
public TestClass(IEnumerable<TEntity> data){
OrderBy = (t) => 1;
ThenOrderBy = (t) => 1;
this.data = data;
}
public IEnumerable<TEntity> Get(Func<TEntity, bool> criteria){
return data.Where(criteria).OrderBy(OrderBy).ThenBy(ThenOrderBy);
}
public Func<TEntity, object> OrderBy { get; set; }
public Func<TEntity, object> ThenOrderBy { get; set; }
}
实例(您可以取消注释ThenOrderBy
行以查看是否使用):http://rextester.com/YFOB38755
顺便说一句,您的现有代码可以更多更易读/更简单:
public virtual List<TEntity> Get(Expression<Func<TEntity, bool>> criteria)
{
IEnumerable<TEntity> query = _dbSet.Where(criteria);
query = OrderDescending ? query.OrderByDescending(OrderBy) : query.OrderBy(OrderBy)
if (paggedSearch)
{
if(Skip > 0)
query = query.Skip(Skip);
if(Take > 0)
query = query.Take(Take);
}
return query.ToList();
}
没有必要继续重复(干!)