Click here to Skip to main content
16,004,927 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have one datatable
Column0           |   Column1   | Column2
04/05/2015 00:10  |   xyz       |  ON
04/05/2015 00:20  |   xyz       |  OFF
04/05/2015 00:30  |   abc       |  ON
04/05/2015 00:40  |   abc       |  OFF

I want this
DateTime         |  SrNo  |  Ontime   | Off Time  |  RunningTime
04/05/2015 00:10 |    1   |    00:10  |   00:20   |    00:10 //(off time) - (on time)


i m using this linq query
C#
var query = MyDataTable.AsEnumerable()
           .Where(r => r.Field<string>("Column0").Contains("04/05/2015"))
           .Where(r => r.Field<string>("Column1").Contains("xyz"))
           //.Select(r => DateTime.Parse(r.Field<string>("Column0")).ToString("dd/MM/yyyy HH:mm:ss"));
           .Select((r, iterator) => new
           {               
               DDate = DateTime.Parse(r.Field<string>("Column0")).ToString("dd/MM/yyyy HH:mm:ss"),
               SrNo = iterator + 1,
               On = r.Field<string>("Column2").Contains("ON"),
               Off = r.Field<string>("Column2").Contains("OFF")
               Running = r.Field<string>("Column2")
           });


How to get correct result

Help me
Posted
Updated 18-Jun-15 6:30am
v2
Comments
Richard Deeming 18-Jun-15 13:14pm    
Don't store dates as strings! Use one of the available date / time types[^] instead.
Manamohan Jha 19-Jun-15 5:50am    
i am not storing dates as string, i am getting all data from CSV file

public DataTable ReadCSV(string filepath)
{
DataTable dtDataSource = new DataTable();
string[] fileContent = File.ReadAllLines(filepath);
if (fileContent.Length > 0)
{
string[] columns = fileContent[0].TrimEnd(',').Split(',');
for (int i = 0; i < columns.Length; i++)
{
dtDataSource.Columns.Add("Column" + i);
}
//
for (int i = 0; i < fileContent.Length; i++)
{
string[] rowData = fileContent[i].TrimEnd(',').Split(',');
dtDataSource.Rows.Add(rowData);
}
}
return dtDataSource;
}

In order to achieve the result you are looking for, you have to group the records based on Column1 and get the result from that.

Here is the LINQ query to get the result you are looking for but not exactly in the same format you asked for. This query requires some minor changes to get the result in the format you need. I am leaving it for you to try.

C#
int iteration = 0;
var result = from dr in MyDataTable.AsEnumerable()
             group dr by dr.Field<string>("column1") into grouped
    select new
    {
        Name = grouped.Key,
        SrNo = ++iteration,
        OnTime = (from dr1 in grouped
                  select dr1.Field<string>("column0")).Min(),
        OffTime = (from dr1 in grouped
                  select dr1.Field<string>("column0")).Max(),
        RunTime = Convert.ToDateTime((from dr1 in grouped
                   select dr1.Field<string>("column0")).Max()) -
                   Convert.ToDateTime((from dr1 in grouped
                    select dr1.Field<string>("column0")).Min())

    };
 
Share this answer
 
Comments
Manamohan Jha 19-Jun-15 10:28am    
it didn't work in my case...
Manamohan Jha 19-Jun-15 10:30am    
var query = hp.ReadCSV(filepath).AsEnumerable()
.Where(r => r.Field<string>("Column1").Contains("xyz"))
.Where(r => (r.Field<string>("Column2") == "ON") || (r.Field<string>("Column2") == "OFF"))
.GroupBy(r => new { DDate = r.Field<string>("Column0"), Type = r.Field<string>("Column1") })
.Select((g, i) => new
{
SrNo = i += 1,
DDate = DateTime.Parse(g.Key.DDate).ToString("dd/MM/yyyy"),
OnTime = g.Where(c => c.Field<string>("Column2") == "ON").Select(c => DateTime.Parse(c.Field<string>("Column0")).ToString("HH:mm:ss")).FirstOrDefault(),
OffTime = g.Where(c => c.Field<string>("Column2") == "OFF").Select(c => DateTime.Parse(c.Field<string>("Column0")).ToString("HH:mm:ss")).FirstOrDefault(),
}).ToArray();

this query work but Off time show in second row

how to correct it??
Check this:

C#
DataTable one = new DataTable();
one.Columns.Add(new DataColumn("Column0", Type.GetType("System.DateTime")));
one.Columns.Add(new DataColumn("Column1", Type.GetType("System.String")));
one.Columns.Add(new DataColumn("Column2", Type.GetType("System.String")));
one.Rows.Add(new Object[]{new DateTime(2015, 5, 4, 0, 10, 0), "xyz", "ON"});
one.Rows.Add(new Object[]{new DateTime(2015, 5, 4, 0, 20, 0), "xyz", "OFF"});
one.Rows.Add(new Object[]{new DateTime(2015, 5, 4, 0, 30, 0), "abc", "ON"});
one.Rows.Add(new Object[]{new DateTime(2015, 5, 4, 0, 40, 0), "abc", "OFF"});


var qry = one.AsEnumerable()
        .GroupBy(r=>new{DDate = r.Field<DateTime>("Column0").ToString(@"yyyy/MM/dd"), Id=r.Field<string>("Column1")})
        .Select((g, i)=>new
            {
                Id = g.Key.Id,
                SrNo = i+=1,
                DDate = g.Key.DDate,
                OnTime = g.Min(c=>c.Field<DateTime>("Column0")).ToString(@"HH:mm:ss"),
                OfTime = g.Max(c=>c.Field<DateTime>("Column0")).ToString(@"HH:mm:ss"),
                RunningTime = (g.Max(c=>c.Field<DateTime>("Column0")) - g.Min(c=>c.Field<DateTime>("Column0"))).TotalMinutes
            });

Result:
Id    SrNo    DDate        OnTime     OfTime     RunningTime
xyz   1       2015-05-04   00:10:00   00:20:00   10 
abc   2       2015-05-04   00:30:00   00:40:00   10 
 
Share this answer
 
Comments
Manamohan Jha 19-Jun-15 3:45am    
i want only "xyz" data...

Column0 | Column1 | Column2
04/05/2015 00:10 | xyz | ON
04/05/2015 00:20 | xyz | OFF
04/05/2015 00:30 | xyz | ON
04/05/2015 00:40 | xyz | OFF
04/05/2015 00:50 | xyz | ON
04/05/2015 00:60 | xyz | OFF
04/05/2015 00:70 | xyz | ON
04/05/2015 00:80 | xyz | OFF
Maciej Los 19-Jun-15 5:52am    
So, what's the problem? Add .Where(c=>c.Field<string>("Column1")=="xyz") statement before GroupBy. Simple?
Manamohan Jha 19-Jun-15 5:57am    
i m not getting correct result

Query:-

var qry = MyDataTable.AsEnumerable()
.Where(r => r.Field<string>("Column1").Contains("xyz"))
.Where(r => (r.Field<string>("Column2") == "ON") || (r.Field<string>("Column2") == "OFF"))
.GroupBy(r => new { DDate = r.Field<string>("Column0") })
.Select((g, i) => new
{
SrNo = i += 1,
DDate = g.Key.DDate,
OnTime = g.Where(c => c.Field<string>("Column2").Contains("ON")).Select(c => Convert.ToDateTime(c.Field<string>("Column0"))).FirstOrDefault(),
OffTime = g.Where(c => c.Field<string>("Column2").Contains("OFF")).Select(c => Convert.ToDateTime(c.Field<string>("Column0"))).LastOrDefault()
});
Manamohan Jha 19-Jun-15 5:58am    
i think Group wish with date field not correct
Some time xyz "ON" and "Off" same time
Maciej Los 19-Jun-15 11:16am    
Because your query is wrong!
1) Second Where is unnecessary!
2) GroupBy does not need new keyword!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900