假设我有一个像这样的数据表:
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 来做,你知道我该怎么做吗?
谢谢
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);
因为你想更新DataTable
我认为没有理由在这里使用 LINQ。相反,我只使用DataTable.Select 方法:
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);
}
First you need to add the System.Data.DataSetExtensions. Then you can select the relevant rows with Where() eg.
var rows=from row in myTable.AsEnumerable()
where row.Field<DateTime>("Date")>=new DateTime(2013,10,22(
select rows;
Then you can modify the row values in a loop:
foreach(var row in rows)
{
row["Price"]=0.98m*(decimal)row["Price"];
}
or, to avoid the boxing and unboxing operations, you can use SetField from the DataSetExtensions:
foreach(var row in rows)
{
row.SetField<decimal>("Price",row.Field<decimal>("Price")*0.98m);
}
If you don't want to update the original rows but you want to get a new table with the matching rows modified, things get a bit trickier. You would have to clone each DataRow in your Select
and set the appropriate field if the date criteria matches.
A simpler solution, would be to simply clone the original table with DataTable.Clone and apply the change to the clone. This won't affect performance as you would copy the original data anyway.
You could do something like this:
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);
}