如何使用linq在一定条件下乘以一列?

时间:2013-07-12 08:20:05

标签: c# linq datatable

假设我有一个数据表:

Date       |  Qty | Price
20/10/2013 |  3   |  1.25
21/10/2013 |  5   |  1 
22/10/2013 |  2   |  0.75
24/10/2013 |  1   |  0.90

如果日期在2013年10月22日之后,我想乘以柱子价格0.98。

我已经为此编写了一些内容,但我想用linq来做,你知道我该怎么做吗?

由于

3 个答案:

答案 0 :(得分:2)

LINQ就是查询而不是更新。您可以使用它来查询应更新的行,但仍需要自己进行更新,例如:使用foreach循环:

foreach(var row in dt.AsEnumerable().Where(x => x.Field<DateTime>("Date") >= myDateTime))
    row.SetField<double>("Price", row.Field<double>("Price") * 0.98);

答案 1 :(得分:1)

因为你想更新DataTable我认为没有理由在这里使用LINQ。相反,我只使用DataTable.Select Method

var d = new DataTable();
d.Columns.Add("Date", typeof(DateTime));
d.Columns.Add("Qty", typeof(int));
d.Columns.Add("Price", typeof(double));
d.Rows.Add(DateTime.ParseExact("20/10/2013", "dd/MM/yyyy",
    CultureInfo.InvariantCulture), 3, 1.25);
d.Rows.Add(DateTime.ParseExact("21/10/2013", "dd/MM/yyyy",
    CultureInfo.InvariantCulture), 5, 1.0);
d.Rows.Add(DateTime.ParseExact("22/10/2013", "dd/MM/yyyy",
    CultureInfo.InvariantCulture), 2, 0.75);
d.Rows.Add(DateTime.ParseExact("24/10/2013", "dd/MM/yyyy",
    CultureInfo.InvariantCulture), 1, 0.90);

foreach (var item in d.Select("Date >= #10/22/2013#"))
{
    item.SetField("Price", item.Field<double>("Price") * 0.98);
}

答案 2 :(得分:0)

首先,您需要添加System.Data.DataSetExtensions。然后,您可以使用Where()例如

选择相关行
var rows=from row in myTable.AsEnumerable()
         where row.Field<DateTime>("Date")>=new DateTime(2013,10,22(
         select rows;

然后您可以在循环中修改行值:

foreach(var row in rows)
{
    row["Price"]=0.98m*(decimal)row["Price"];
}

或者,为避免装箱和拆箱操作,您可以使用DataSetExtensions中的SetField

foreach(var row in rows)
{
    row.SetField<decimal>("Price",row.Field<decimal>("Price")*0.98m);
}

如果您不想更新原始行,但是想要获得一个修改了匹配行的新表,那么事情会变得有点棘手。您必须克隆Select中的每个DataRow,并在日期条件匹配时设置相应的字段。

更简单的解决方案是简单地使用DataTable.Clone克隆原始表并将更改应用于克隆。这不会影响性能,因为您仍然会复制原始数据。

你可以这样做:

var myCopy=myTable.Clone();
var rows=from row in myClone.AsEnumerable()
         where row.Field<DateTime>("Date")>=new DateTime(2013,10,22(
         select rows;
foreach(var row in rows)
{
    row.SetField<decimal>("Price",row.Field<decimal>("Price")*0.98m);
}