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);
}