【问题标题】:Multiple 'Or' statements in EF expressionEF 表达式中的多个“或”语句
【发布时间】:2013-09-17 09:31:38
【问题描述】:

给定一个过滤器参数列表,格式为:

public class filterParm
{
    public int age { get; set; }
    public string name { get; set; }
}

地点:

var parms = new List<filterParm>
{
    new filterParm {age = 22, "phil"},
    new filterParm {age = 19, "dave"},
    new filterParm {age = 31, "nick"}
};

我如何编写一个表达式,它会导致以下 SQL where 子句(注意粗体的 OR 运算符:

WHERE(年龄 = 22 AND 姓名 = “phil”)
(年龄 = 19 AND 姓名 = “dave”) (年龄 = 31 AND 姓名 = “昵称”)

我当前的实现导致由 AND 运算符分隔的每个语句:

private _dbSet<user> Users { get; set; }
public List<user> CustomFilter(List<filterParm> parms)
{
    IQueryable<TEntity> query = _dbSet;

    if (parms.Count > 0 )
    {
        foreach (var parm in parms)
        {                    
           query = query.Where(u => u.Age == parm.Age && u.Name == parm.Name);
        }
    }

    return query.ToList();
}

上面的代码产生如下 SQL:

WHERE (age = 22 AND name = "phil") AND (age = 19 AND name = "dave") AND (年龄 = 31 AND name = "nick")

我需要在表达式中进行哪些更改以使生成的 SQL 在指定位置使用“OR”而不是“AND”?我希望尽可能避免使用第三方库。

编辑: 正如@KingKing 所建议的,union 确实会返回所需的结果:

private _dbSet<user> Users { get; set; }
public List<user> CustomFilter(List<filterParm> parms)
{
    IQueryable<TEntity> query = _dbSet;

    if (parms.Count > 0)
    {
        query = query.Where(u => u.Age == parms[0].Age && u.Name == parms[0].Name);

        for (int i = 1; i < parms.Count; i++)
        {
            var parm = parms[i];
            query = query.Union(DbSet.Where(u => u.Age == parm.Age && u.Name == parm.Name));
        }                                                   
    }
    return query.ToList();
}

我仍然想知道是否可以使用 'Or' 运算符生成语句。

【问题讨论】:

标签: c# entity-framework-4 odac


【解决方案1】:

我认为使用Union 会有所帮助:

public List<user> CustomFilter(List<filterParm> parms) {
  IQueryable<TEntity> query = _dbSet;
  if (parms.Count > 0 ){
    IQueryable<TEntity> init = _dbSet;
    var firstParm = parms[0];
    query = query.Where(u => u.Age == firstParm.Age && u.Name == firstParm.Name);
    for(int i = 1; i < parms.Count; i++)
    {                    
       var nextParm = parms[i];
       init = init.Where(u => u.Age == nextParm.Age && u.Name == nextParm.Name);
       query = query.Union(init);
    }
  }
  return query.ToList();
}

【讨论】:

  • 第二个不能转成EF。不能在 contains 中使用引用类型:(
  • @WouterdeKort 谢谢,看起来EF 有很多限制:(
  • @KingKing Concat 生成了使用 AND 运算符而不是 OR 运算符的 SQL,此外它还生成了一个包含许多绑定变量的非常复杂的语句。要么这不合适,要么我做错了......可能是后者。
  • @philreed 我不知道translated SQL是使用OR还是AND,但是使用OR时结果应该是一样的。
  • @philreed 我用Union 更新了,应该是更好的选择。
猜你喜欢
  • 1970-01-01
  • 2013-12-07
  • 2020-05-10
  • 2020-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-25
相关资源
最近更新 更多