如何在foreach循环中使用两个变量?

时间:2013-08-15 17:47:35

标签: c# linq foreach

我使用dotConnect linq到sqlite。我想要做的是在foreach循环中使用两个变量。遵循this代码,但它无效。这是我的代码段。

    bool check_units(int id)
    {
        MainDataContext medic = new MainDataContext();
        bool check = false;
        var medic_query = from m in medic.Medicines
                          orderby m.Id
                          where m.Id == id
                          select m;

        var invo_query = from inv in medic.Invoices
                         orderby inv.Id
                         where inv.Id == id
                         select inv;

        var med_inv = medic_query.Zip(invo_query, (m, i) => new { Medicine = m, Invoice = i });

        foreach(var mi in med_inv)
        {
            if (mi.Medicine.UNIT > mi.Invoice.UNIT)
            {
                mi.Medicine.UNIT -= mi.Invoice.UNIT;
                if (mi.Medicine.UNIT < 10)
                {
                    MessageBox.Show(mi.Medicine.Name + " is short in Invertory!\nUnits Remaining: " + mi.Medicine.UNIT,
                        "Inventory Empty", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
                chk = true;
            }
            else
            {
                MessageBox.Show("Not Enough Stock!\nUnits Remaining: " + mi.Medicine.UNIT,
                    "Inventory Short", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        medic.SubmitChanges();
        return chk;
    }

我面临的问题是我的代码出错了

  

不支持查询运算符“Zip”。

没有任何语法错误或警告。 我认为Zip运算符不能与linqtosql类型的查询一起使用!

等待支持! 谢谢:))

3 个答案:

答案 0 :(得分:3)

问题是底层查询提供程序无法将Zip方法转换为原始SQL。由于您没有应用任何其他过滤器,因此最简单的方法是使用AsEnumerable来润滑查询:

    var med_inv = medic_query.AsEnumerable()
                             .Zip(invo_query, (m, i) => new { Medicine = m, Invoice = i });

您确定每个查询的记录都正确排列吗?这看起来应该是Join,但由于您没有指定记录是否/如何相关,我们无法确定正确的连接是什么。

答案 1 :(得分:2)

您看到的问题与Zip提供程序不支持的IQueryable<T>方法有关。强制将数据移动到内存应该可以解决这个问题 - 您可以使用AsEnumerable进行强制转换,或者将数据显式地存储在内存中,如下所示:

var medList = medic_query.ToList();
var invoList = invo_query.ToList();
var med_inv = medList.Zip(invoList, (m, i) => new { Medicine = m, Invoice = i });

这不会对性能产生太大影响,因为Zip无论如何都会将两个列表都带入内存。

答案 2 :(得分:2)

添加AsEnumerable()调用:

var med_inv = medic_query.AsEnumerable().Zip(invo_query.AsEnumerable(), (m, i) => new { Medicine = m, Invoice = i });