我有一个具有以下签名的方法,该方法返回 C# 表达式
Expression<Func<T, bool>> GetExpression<T>(IList<Filter> filters)
然后是使用动态 LINQ 的以下代码
using (TestContext tEntities = new TestContext())
{
var filterExp = Exp.ExpressionBuilder.GetExpression<Client>(filters);
var filteredCollection = tEntities.Client.Where(filterExp);
IQueryable<Client> queryResult;
if (filterExp == null)
queryResult = tEntities.Client;
else
queryResult = tEntities.Client.Where(filterExp);
}
这是一个简单的场景。 我的查询有时长达 50 行。我想避免使用 where 子句两次使用相同的代码,而仅有差异。
有人知道我是否取得了不同的成就吗?
from product in context.Product.Where(deleg)
.Include(x => x.Type)
.Include(x => x.Category)
.Include(x => x.WareHouse)
.Include(x => x.Photos)
join f in context.Favorite on product.Id equals f.ProductFid into fg
from fgi in fg.Where(f => f.UserFid == userId).DefaultIfEmpty()
orderby product.Id descending
select new ProductngDto()
{
ProductItem = product,
FavoriteId = fgi != null ? fgi.Id : (long?)null
}).Skip(page * pageSize).Take(pageSize);
提前致谢
最佳答案
关于 IQueryable<T>
的好处之一和IEnumerable<T>
事实上,它们是如此抽象,你可以轻松地将它们链接在一起。一种解决方案可能是像这样构建代码:
using (TestContext tEntities = new TestContext())
{
var filterExp = Exp.ExpressionBuilder.GetExpression<Client>(filters);
var filteredCollection = tEntities.Client.Where(filterExp);
IQueryable<Client> queryResult = tEntities.Client;
if (filterExp != null)
{
queryResult = queryResult.Where(filterExp);
}
//do something else with queryResult
}
这样您就可以继续使用 queryResult
无需知道,甚至不必关心是否filterExp
已应用。
对于第二个示例,将其打乱可能看起来像这样:
var query = from p in context.Product
.Include(x => x.Type)
.Include(x => x.Category)
.Include(x => x.WareHouse)
.Include(x => x.Photos);
if (deleg != null)
{
query = query.Where(deleg);
}
query = from product in query
join f in context.Favorite on product.Id equals f.ProductFid into fg
from fgi in fg.Where(f => f.UserFid == userId).DefaultIfEmpty();
orderby product.Id descending
select new ProductngDto()
{
ProductItem = product,
FavoriteId = fgi != null ? fgi.Id : (long?)null
}).Skip(page * pageSize).Take(pageSize);
您的另一个选择是检查 filterExp
为 null 并为其分配一个“始终为真”的 lambda。
如果你控制GetExpression<T>
方法,您可以将其添加到那里作为最后一步。如果您不控制它,您可以在使用其结果的方法中进行空检查。
这将使您的代码看起来更简洁,但代价是必须始终评估 lambda,从而对性能造成一点影响。
根据表达式的输入方式,这可能很简单:
if (filterExp == null)
{
filterExp = (_) => true;
}
关于c# - 使用动态 LINQ 的空表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41320543/