C# 使用多个OR语句生成实体框架查询
目前我有一个列表(C# 使用多个OR语句生成实体框架查询,c#,entity-framework,tuples,C#,Entity Framework,Tuples,目前我有一个列表(List)表示时间范围的列表。 现在我想创建一个通用列表,从中选择这些范围内的所有记录 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<
List)
表示时间范围的列表。
现在我想创建一个通用列表,从中选择这些范围内的所有记录
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);
})
有什么聪明的解决方案吗?您应该使用表达式动态创建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);
List totalPerson=新列表{
新人{Id=1,CreateTime=newdatetime(2018,10,2)},
新人{Id=2,CreateTime=newdatetime(2018,10,3)},
新人{Id=3,CreateTime=newdatetime(2018,10,4)},
新人{Id=4,CreateTime=newdatetime(2018,10,6)},
新人{Id=5,CreateTime=newdatetime(2018,10,7)},
新人{Id=6,CreateTime=newdatetime(2018,10,8)},
新人{Id=7,CreateTime=newdatetime(2018,10,11)},
新人{Id=8,CreateTime=newdatetime(2018,10,12)},
新人{Id=9,CreateTime=newdatetime(2018,10,13)},
新人{Id=10,CreateTime=newdatetime(2018,10,16)},
新人{Id=11,CreateTime=newdatetime(2018,10,17)},
新人{Id=12,CreateTime=newdatetime(2018,10,18)}
};
列表范围=新列表{
新元组(新日期时间(2018,10,1)、新日期时间(2018,10,5)),
新元组(新日期时间(2018,10,10),新日期时间(2018,10,15))
};
IQueryable persons=totalPerson.Where(t=>t.Id>0.AsQueryable();
var参数=表达式参数(typeof(Person),“t”);
BinaryExpression BinaryExpression=null;
范围。ForEach(范围=>
{
MemberExpression Field=Expression.PropertyOrField(参数“CreateTime”);
var startTime=表达式常数(范围.Item1);
var endTime=表达式常数(范围项2);
var expressionItem1=表达式.GreaterThanOrEqual(已存档,开始时间);
var expressionItem2=表达式.lessthanRequal(已存档,结束时间);
var expressionItem=Expression.And(expressionItem1,expressionItem2);
if(binaryExpression==null)
{
binaryExpression=expressionItem;
}
其他的
{
binaryExpression=Expression.Or(binaryExpression,expressionItem);
}
});
表达式条件=Expression.Lambda(二进制表达式,参数);
var结果=人,其中(条件);
元组可以直接在Where
子句中使用
var result = (from i in items
from r in ranges
where i.date >= r.Item1 && i.date <= r.Item2
select i).ToList();
var result=(来自项目中的i)
从r到r的范围
其中i.date>=r.Item1&&i.date由于我的实体框架版本不能处理元组的限制,我使用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);
}
public List GetList(项目){
IQueryable qMyobjects=this.GetQueryableList(item,item.ranges.first().item1,item.ranges.first().item2;
item.ranges.Skip(1).ToList().ForEach((元组范围)=>{
IQueryable select=this.GetQueryableList(item,range.item1,range.item2);
qMyobjects=qMyobjects.Union(选择);
});
返回qMyobjects.ToList();
}
受保护的IQueryable GetQueryableList(项项、日期时间日期从、日期时间日期到){
return\u context.myobjects
其中(e=>e.category.Equals(“somecategory”)
哪里(e=>e.date>=dateFrom&&e.date是否要选择存在一个或多个范围且该范围在该范围之间的所有项目?这可能会对您有所帮助:我要选择日期在给定范围内的所有项目。可能我的解释是错误的,但是的此查询是否只包含tupl的过滤器相似的项目?我需要筛选日期在该日期范围之间的项目。让我再次检查:)@SNO,在上面的更新查询中,我从数据库中获取元组列表中两个日期范围内的数据。感谢您提供的解决方案。不幸的是,我得到了一个“System.NotSupportedException”。可能是因为将元组与我们的Oracle数据库结合使用。@SNO,在我的机器上使用sql server非常有效。也许您可以使用sql server进行尝试。如果我的答案对您有帮助,您可以选择在答案的左侧打勾,使其变为绿色,并进行投票
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);
}