如何将 LINQ 查询连接起来?

6

我有一个表单,根据用户的选择过滤数据。

我试图将linq查询追加到一起,以便最终结果是他们在屏幕上选择的内容。

这是我的代码:

private void button_Search_Click(object sender, EventArgs e)
{
  using (var model = new SuburbanPortalEntities())
  {
    var qry = from logs in model.Logs
              select logs;

    Guid corpid;
    if (Guid.TryParse(textBox_CorporationGuid.Text, out corpid))
    {
      qry = from logs in model.Logs
                where logs.CorporationId == corpid
                select logs;
    }

    Guid tokenid;
    if (Guid.TryParse(textBox_TokenId.Text, out tokenid))
    {
      qry = from logs in model.Logs
            where logs.TokenId == tokenid
            orderby logs.LogDateTime descending 
            select logs;
    }

    if (checkBox_DisplayErrors.Checked)
    {
      qry = from logs in model.Logs
            where logs.IsException
            select logs;
    }

    if (checkBox_DisplayWarnings.Checked)
    {
      qry = from logs in model.Logs
            where logs.IsWarning
            select logs;
    }

    dataGridView1.DataSource = qry;


  }
}

我运气不好,最后一个qry是在我的DataGridView上显示的。

有人可以告诉我哪里出了问题吗?

谢谢!


从您的第二个查询中,您可以从先前查询返回的结果中进行查询。 - zs2020
你每次都用新的结果覆盖变量 qry,就像执行 int a = 0; a = 1; 一样。 - sinelaw
4个回答

10
这里发生的情况是,每次重新定义了源数据中的qryqry 是一个 IEnumerable<T>,与 logs 相同,因此您应该能够这样替换您的代码:
 var qry = model.Logs;

 if( // Condition )
    qry = qry.Where(x => x.CorporationId == corpId);

 if( // Another condition)
    qry = qry.Where(x => x.IsException);

设置完成后,qry将由所有已选择的Where子句组成,并应该仅生成您要查找的项目。


4
"qry" 是一个 "IQueryable<T>" 而不是 "IEnumerable<T>",尽管 "IQueryable<T>" 继承自 "IEnumerable<T>"。这是非常重要的区别。 - Servy

6
你可以使用linq的Concat函数:
qry = qry.Concat(
            from logs in model.Logs
            where logs.CorporationId == corpid
            select logs);

另一方面,您可能希望根据条件创建查询,选择适当的结果,这样您将只需要查询数据源一次。


1
OP可能想要Concat(它附加结果),而不是Union(执行集合并)。 - sinelaw
谢谢,我已经编辑了我的答案,包括Concat方法,因为这可能是OP想要的。 - Zbigniew
请注意,根据具体情况,使用 Concat 不一定涉及两个数据库查询。查询提供程序可以将查询组合并导致发送到数据库的单个查询。 - Servy

0
尝试使用Concat函数:
private void button_Search_Click(object sender, EventArgs e)
{
  using (var model = new SuburbanPortalEntities())
  {
    var qry = (from logs in model.Logs
              select logs).ToList();

Guid corpid;
if (Guid.TryParse(textBox_CorporationGuid.Text, out corpid))
{
  qry.Concat((from logs in model.Logs
            where logs.CorporationId == corpid
            select logs).ToList());
}

Guid tokenid;
if (Guid.TryParse(textBox_TokenId.Text, out tokenid))
{
  qry.Concat(from logs in model.Logs
        where logs.TokenId == tokenid
        orderby logs.LogDateTime descending 
        select logs).ToList());
}

if (checkBox_DisplayErrors.Checked)
{
  qry.Concat((from logs in model.Logs
        where logs.IsException
        select logs).ToList());
}

if (checkBox_DisplayWarnings.Checked)
{
  qry.Concat((from logs in model.Logs
        where logs.IsWarning
        select logs).ToList());
}

dataGridView1.DataSource = qry;

} }


0

我建议使用LinqKit中的Predicate Builder函数。您可以使用And和Or方法附加其他搜索参数。

我曾经为了这个目的使用过它,效果非常好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接