简体   繁体   中英

Find single record using C# linq from datatable

I have a datatable from which a single record[datarow] has to be fetch using LINQ or Lambda expression.

in the filter data function I have tried out different way to find that record. But none of them work

The condition is, find a record with minimum date where available seat is greater than zero

SO the answer would be ("kjgsdjf", "12-Apr-2019", 1)

Can someone help me to write that single line query?

public class LicenseData
{
    public DataTable dt = null;

    public LicenseData()
    {
        CreateTable();
        FillTable();
        FilterData();
    }

    private void CreateTable()
    {
        dt = new DataTable();
        dt.Columns.Add(new DataColumn("Token", typeof(String)));
        dt.Columns.Add(new DataColumn("CreatedAt", typeof(String)));
        dt.Columns.Add(new DataColumn("AvailableSeat", typeof(Int32)));
    }

    private void FillTable()
    {
        dt.Rows.Add("jhgadjd", "20-May-2019", 0);
        dt.Rows.Add("regfhetuy", "28-May-2019", 15);
        dt.Rows.Add("rtsvxfg", "27-May-2019", 10);
        dt.Rows.Add("dhdgcv", "15-May-2019", 60);
        dt.Rows.Add("wrweref", "01-Jun-2019", 5);
        dt.Rows.Add("mmhbdfxb", "05-May-2019", 2);
        dt.Rows.Add("idhfk", "11-May-2019", 8);
        dt.Rows.Add("kjhsdkjfh", "03-Jul-2019", 10);
        dt.Rows.Add("msdkh", "19-Jun-2019", 0);
        dt.Rows.Add("jhgdsjf", "13-Apr-2019", 0);
        dt.Rows.Add("kjgsdjf", "12-Apr-2019", 1);

    }

    private void FilterData()
    {
        var first = dt.Select("AvailableSeat>0").AsEnumerable();
        var result = first.Min(r => Convert.ToDateTime(r.Field<string>("CreatedAt")));

        IOrderedEnumerable<DateTime> idr = dt.Rows.OfType<DataRow>().Select(k => Convert.ToDateTime(k["CreatedAt"])).OrderBy(k => k);

        var result1 = dt.AsEnumerable()
           .Select(cols => Convert.ToDateTime(cols.Field<string>("CreatedAt")))
           .OrderBy(p => p.Ticks);


        DataRow dr = dt.Select("AvailableSeat>0").AsEnumerable().Min<DataRow>(r =>  r);
    }

Having a DateTime represented as a string makes it practically impossible to sort or search, so your first change is keeping a datetime as a datetime in your table.

private void CreateTable()
{
    dt = new DataTable();
    dt.Columns.Add(new DataColumn("Token", typeof(String)));
    dt.Columns.Add(new DataColumn("CreatedAt", typeof(DateTime)));
    dt.Columns.Add(new DataColumn("AvailableSeat", typeof(Int32)));
}

Next when you fill the table you parse the input string with the Invariant Culture to store it as a date

private void FillTable()
{
    dt.Rows.Add("jhgadjd", DateTime.Parse("20-May-2019", CultureInfo.InvariantCulture), 0);
    ....
}

At this point to resolve the query you can have a single line expression

// Remove the 0 entries and sort them by date CreatedAt
var result1 = dt.AsEnumerable().Where(x => x.Field<int>("AvailableSeat") > 0)
                .OrderBy(d => d.Field<DateTime>("CreatedAt"));

// Get the first row in the result1
DataRow firstNotEmpty = result1.FirstOrDefault();

I think this answer should give you what you're looking for. This is in Linqpad program format.

    void Main()
{
    var foo = new LicenseData();


}
// Define other methods and classes here

public class LicenseData
{
public DataTable dt = null;

public LicenseData()
{
    CreateTable();
    FillTable();
    FilterData();
}

private void CreateTable()
{
    dt = new DataTable();
    dt.Columns.Add(new DataColumn("Token", typeof(String)));
    dt.Columns.Add(new DataColumn("CreatedAt", typeof(String)));
    dt.Columns.Add(new DataColumn("AvailableSeat", typeof(Int32)));
}

private void FillTable()
{
    dt.Rows.Add("jhgadjd", "20-May-2019", 0);
    dt.Rows.Add("regfhetuy", "28-May-2019", 15);
    dt.Rows.Add("rtsvxfg", "27-May-2019", 10);
    dt.Rows.Add("dhdgcv", "15-May-2019", 60);
    dt.Rows.Add("wrweref", "01-Jun-2019", 5);
    dt.Rows.Add("mmhbdfxb", "05-May-2019", 2);
    dt.Rows.Add("idhfk", "11-May-2019", 8);
    dt.Rows.Add("kjhsdkjfh", "03-Jul-2019", 10);
    dt.Rows.Add("msdkh", "19-Jun-2019", 0);
    dt.Rows.Add("jhgdsjf", "13-Apr-2019", 0);
    dt.Rows.Add("kjgsdjf", "12-Apr-2019", 1);

}

private void FilterData()
{
    var first = dt.Select("AvailableSeat>0").AsEnumerable();
    var result = first.Min(r => Convert.ToDateTime(r.Field<string>("CreatedAt")));

    IOrderedEnumerable<DateTime> idr = dt.Rows.OfType<DataRow>().Select(k => Convert.ToDateTime(k["CreatedAt"])).OrderBy(k => k);

    var result1 = dt.AsEnumerable()
       .Select(cols => Convert.ToDateTime(cols.Field<string>("CreatedAt")))
       .OrderBy(p => p.Ticks);


var dr = dt.Select("AvailableSeat>0").OrderBy(x => DateTime.Parse(x[1].ToString())).First();
    dr.Dump();
}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM