当前,我有一个列表(List<Tuple<DateTime, DateTime>>)
代表时间范围列表。
现在,我想创建一个通用列表,从中选择这些范围内的所有记录。
List<Tuple<DateTime, DateTime>> ranges = new List<Tuple<DateTime, DateTime>>{
new Tuple<DateTime, DateTime(new Date(2018,01,01), new Date(2019,01,01)}
IQueryable<item> items = context.items.Where(e => e.category.equals("somecategory"));
ranges.ForEach((Tuple<DateTime, DateTime) range => {
items = items.Where(e => e.date >= range.Item1 && e.date <= range.Item2);
})
最后一个循环应使用“ OR”扩展语句,以便具有
.Where(e => e.date between range1 || e.date between range2 || ...).
有什么聪明的解决方案吗?
答案 0 :(得分:1)
Tuple
可以直接在Where
子句中使用,例如
var result = (from i in items
from r in ranges
where i.date >= r.Item1 && i.date <= r.Item2
select i).ToList();
答案 1 :(得分:0)
您应该使用Expression动态创建lambda表达式,例如:
List<Person> totalPerson = new List<Person> {
new Person{ Id = 1,CreateTime = new DateTime(2018,10,2)},
new Person{ Id = 2,CreateTime = new DateTime(2018,10,3)},
new Person{ Id = 3,CreateTime = new DateTime(2018,10,4)},
new Person{ Id = 4,CreateTime = new DateTime(2018,10,6)},
new Person{ Id = 5,CreateTime = new DateTime(2018,10,7)},
new Person{ Id = 6,CreateTime = new DateTime(2018,10,8)},
new Person{ Id = 7,CreateTime = new DateTime(2018,10,11)},
new Person{ Id = 8,CreateTime = new DateTime(2018,10,12)},
new Person{ Id = 9,CreateTime = new DateTime(2018,10,13)},
new Person{ Id = 10,CreateTime = new DateTime(2018,10,16)},
new Person{ Id = 11,CreateTime = new DateTime(2018,10,17)},
new Person{ Id = 12,CreateTime = new DateTime(2018,10,18)}
};
List<Tuple<DateTime, DateTime>> ranges = new List<Tuple<DateTime, DateTime>>{
new Tuple<DateTime, DateTime>(new DateTime(2018,10,1), new DateTime(2018,10,5)),
new Tuple<DateTime, DateTime>(new DateTime(2018,10,10), new DateTime(2018,10,15))
};
IQueryable<Person> persons = totalPerson.Where(t => t.Id > 0).AsQueryable();
var parameter = Expression.Parameter(typeof(Person), "t");
BinaryExpression binaryExpression = null;
ranges.ForEach(range =>
{
MemberExpression filed = Expression.PropertyOrField(parameter, "CreateTime");
var startTime = Expression.Constant(range.Item1);
var endTime = Expression.Constant(range.Item2);
var expressionItem1 = Expression.GreaterThanOrEqual(filed, startTime);
var expressionItem2 = Expression.LessThanOrEqual(filed, endTime);
var expressionItem = Expression.And(expressionItem1, expressionItem2); ;
if (binaryExpression == null)
{
binaryExpression = expressionItem;
}
else
{
binaryExpression = Expression.Or(binaryExpression, expressionItem);
}
});
Expression<Func<Person, bool>> condition = Expression.Lambda<Func<Person, bool>>(binaryExpression, parameter);
var results = persons.Where(condition);
答案 2 :(得分:0)
由于我的限制,我们的Entity Framework版本无法处理元组,因此我使用Union
解决了该问题:
public List<MyObject> GetList(Item item){
IQueryable<MyObject> qMyobjects = this.GetQueryableList(item, item.ranges.first().item1, item.ranges.first().item2;
item.ranges.Skip(1).ToList().ForEach((Tuple<DateTime, DateTime> range) => {
IQueryable<MyObject> select = this.GetQueryableList(item, range.item1, range.item2);
qMyobjects = qMyobjects.Union(select);
});
return qMyobjects.ToList();
}
protected IQueryable<MyObject> GetQueryableList(Item item, DateTime dateFrom, DateTime dateTo){
return _context.myobjects
.Where(e => e.category.Equals("somecategory")
.Where(e => e.date >= dateFrom && e.date <= dateTo);
}