Having trouble trying to implement a query on dataset/datatable - c#

I have a data set say 'ds' which I populate from a table called tran_dtls ,
now I want to write a method to this data set(or the table in the data set 'dt'),which would effectively retrieve for me a scalar value having the same output as this query:
select sum(amt) from TRAN_DTLS
where GL_CODE='" + row["gl_code"].ToString() + "'
and SUB_CODE='" + row["sub_code"].ToString() + "'
and DBCR='C'"
Here amt,GL_code,SUb_code,DBCR are the columns in tran_dtls table, So what I want to do is select the sum of amount having various conditions ,I have never done anything like this before so I don't know even this would be possible or not

I don't think you can write SQL against a DataSet. But you can use LINQ:
var ds = new DataSet();
var tranDtls = new DataTable("tran_dtls");
tranDtls.Columns.Add("gl_code", typeof(string));
tranDtls.Columns.Add("amt", typeof(int));
var row = tranDtls.NewRow();
row["gl_code"] = "a";
row["amt"] = 1;
tranDtls.Rows.Add(row);
ds.Tables.Add(tranDtls);
var result = ds.Tables["tran_dtls"].AsEnumerable()
.Where(r => (string)r["gl_code"] == "a")
.Select(r => (int)r["amt"])
.Sum();

Related

How to use linq query to get value in datatable

That consist of 2 columns: roomType and no rooms
So I want to get no rooms value from room type that i have.
In SQL its look like this:
SELECT no_rooms from table name where roomtype = 'deluxe'
Result: 2
How to access that in LINQ query and store that value as int datatype?
I only know this code
string[] tableName = table.AsEnumerable()
.Select(s => s.Field<string>("NoRooms"))
.ToArray<string>()
.Where(?idont_know_the_query));
var results = from myRow in table.AsEnumerable()
where myRow.Field<String>("roomtype ") == "deluxe"
select myRow;
Here is just another way of retriving the data rows, assuming that table in your example is a DataTable
string expression = string.Format("roomtype='{0}'","deluxe");
var rows = dt.Select(expression);
var strRoomNumber = rows.Select(r=>r.Field<string>("roomNumber")).FirstOrDefault();
int no_rooms;
int.TryParse(strRoomNumber,out no_rooms);
This will return you the first no of rooms for the first matching record
var NoOfRooms= tablename.where(x=>x.roomType=="deluxe").ToList();
int total = NoOfRooms.count();

take top 10 or 20 rows from dynamic datatable

I have 100 records in my Datable says to be in
DataTable dt=new DataTable();
dt have 100 of records say column name as sub_id(contain int datatype) and subheadername(contain nvarchar(150)) , I want top 20 records from this dt in ascending order
I am putting code as
//dtlcategories.DataSource = dt.AsEnumerable().OrderBy(x => x["subheadername"]).Take(20).ToList();
dtlcategories.DataSource = dt.Rows.Cast<DataRow>().OrderBy(x => x["subheadername"]).Take(20).ToList();
dtlcategories.DataBind();
Here dtlcategories is Datalist but on running error is coming as 'System.Data.DataRow' does not contain a property with the name 'subheadername'.
ANSWER IS SOLVED
dtlcategories.DataSource = dt.Rows.Cast<DataRow>().OrderBy(x => x["subheadername"]).Take(20).copytodatatable();
dtlcategories.DataBind();
There's a couple different ways you can do this using LINQ. These will both return the same results.
dt.AsEnumerable().OrderBy(x => x["subheadername"]).Take(20);
dt.Rows.Cast<DataRow>().OrderBy(x => x["subheadername"]).Take(20);
If you're going to use the result as the source of data for another control, you may need to call .ToList() after .Take(x).
Edit:
I changed the column name based on your edit. If you want to sort by id instead (you didn't specify), just replace "subheadername" with "sub_id".
This query fetches top 20 records from db and then orders them by the sub_id column.
var topTwenty = dt.AsEnumerable().Take(20).OrderBy(r => r.Field<int>("sub_id"));
dt.AsEnumerable().OrderBy(row => row["sub_id"]).Take(20);
This will return you IEnumerable. Now iterate through the IEnumerable and add them to another data table. Now your final data table is ready!!
this code orders data according to date and takes first 100 row.
var table = new DataTable();
var t = table.AsEnumerable();
var result = t.OrderByDescending(f => f.Field<DateTime>(new DataColumn("Date"))).Take(100);
Update:
var table = new DataTable();
var t = table.AsEnumerable();
var result = t.OrderBy(f => f.Field<String>(new DataColumn("subheadername"))).Take(20)
A possible solution:
DataRow[] rows = dt.Select("sub_id< 100 ");

Filter data from DataTable

DataTable dtt = (DataTable)Session["ByBrand"];
var filldt = (dtt.Select("Price >= " + HiddenField1.Value + " and Price <= " + HiddenField2.Value + "")).CopyToDataTable();
this code is working fine when it found values in selected DataTable but it showing error when Values are not found in DataTable. So please tell me how to check if no record found.
Simply check if your Select returns anything?
DataTable dtt = (DataTable)Session["ByBrand"];
DataRow[] rows = dtt.Select("Price >= " + HiddenField1.Value + " and Price <= " + HiddenField2.Value + "");
if(rows.Length > 0)
{
var filldt = rows.CopyToDataTable();
}
Well, the Linq example from Tim is really nice, but to complete my answer.
The Select method returns Always a DataRow array also if there is no row selected, but then you cannot ask to build a datatable from this empty array. Think about it. What schema the CopyToDataTable should build for the resulting table if no rows are present in the array?
You have tagged Linq but you are using DataTable.Select which is an old method to filter a DataTable. Use Enumerable.Where and the strongyl typed Field extension method.
decimal priceFrom = decimal.Parse(HiddenField1.Value);
decimal priceTo = decimal.Parse(HiddenField2.Value);
var dtFiltered = dtt.AsEnumerable()
.Where(row => row.Field<decimal>("Price") >= priceFrom
&& row.Field<decimal>("Price") <= priceTo))
.CopyToDataTable();
Presuming that the type of the column is decimal, if it's a different type you need to use that in Field or convert it first.
Note that you need to add System.Linq(file) and a reference to System.Data.DataSetExtensions(project).
Update
but it showing error when Values are not found in DataTable
CopyToDataTable throws an exception if the input sequence is empty. In my opinion the best approach is to handle that case separately:
DataTable tblFiltered = dtt.Clone(); // clones only structure not data
var filteredRows = dtt.AsEnumerable()
.Where(row => row.Field<decimal>("Price") >= priceFrom
&& row.Field<decimal>("Price") <= priceTo));
if(filteredRows.Any())
{
tblFiltered = filteredRows.CopyToDataTable();
}
or this approach that might be more efficient since it doesn't need to use Any which can cause an additional full enumeration in worst case:
foreach(DataRow row in filteredRows)
{
tblFiltered.ImportRow(row);
}

Filtering entire DataSet with many DataTables

I have a DataSet with many DataTables each containing many columns plus a column buildingID.
I would like to filter the entire DataSet by giving it a value for buildingID. I would like the rows in every table with a buildingID of, say 343.
Is there any quick possible way in C#?
You can use DataTable.Select, which returns filtered rows from a DataTable matching a criteria.
foreach (DataTable table in dataset.Tables) {
var rows = table.Select("buildingID = " + buildingId.ToString());
// Do stuff with filtered rows
}
To easily get all the rows that match your criteria, here's a LINQ expression:
var rows = dataset.Tables.SelectMany(
t => t.Select("buildingID = " + buildingId.ToString()));
What about this?
var ds1 = new DataSet();
foreach (DataTable dt in ds1.Tables)
{
var filtereddt = dt.AsEnumerable().Where(row => row.Field<int>("buildingID") == 1).ToList();
//you can add these lists to another list array or something like that.
}

Any data table query builder available, like sql query builder?

I am new in net I want to use data table instead of a database.
I want to know that why is data table query different from an sql query?
I want to find a value from data table:
SELECT dbo.General_Ledger.Entry_Amount FROM dbo.General_Ledger WHERE Account_number=lbDebit_Account_numer
and
using (SqlConnection connect = new SqlConnection(con))
{
int index = lbDebit_Account.FindString(txtDebit_Account.Text);
if (0 <= index)
{
lbDebit_Account.SelectedIndex = index;
}
SqlDataAdapter da3 = new SqlDataAdapter("SELECT *FROM dbo.General_Ledger", connect);
DataTable dt1 = new DataTable();
da3.Fill(dt1);
string lbDebit_Account_numer = lbDebit_Account.SelectedValue.ToString();
string row;
row= Convert.ToString(dt1.Select(string.Format("'Account_number'={0}",lbDebit_Account_numer)));
}
I want to perform this query:
SELECT dbo.General_Ledger.Entry_Amount FROM dbo.General_Ledger WHERE Account_number=lbDebit_Account_numer
So you'll want to parameterize your query:
SqlDataAdapter da3 = new SqlDataAdapter("SELECT * FROM dbo.General_Ledger WHERE Account_number = #Account_number");
da3.SelectCommand.Parameters.AddWithValue("#Account_number", lbDebit_Account.SelectedValue);
DataTable dt1 = new DataTable();
da3.Fill(dt1);
and now you'll have just the one row you want and you can recover it like this:
DataRow dr = dt1.Rows[0];
and then you can grab values off of that row a number of different ways:
var val = dr[0]; // grabs the value of the first column in the result list
var val = dr["fieldname"] // grabs the value of a specific field name
and there are even some methods that will returned typed data because the aforementioned return an object since the underlying value could be a number of things. So, if it were a string field you were after you could do something like:
var val = dr.Field<string>(0) // grabs the value of the first column and returns it typed as a string
var val = dr.Field<string>("fieldname") // grabs a field and returns it typed as a string
It very simple, u want to filter the DataTable[dt1] base on this string[lbDebit_Account_numer]
DataRow dr = dt1.Select("Account_number = '"+lbDebit_Account_numer ="'");
u can use
AND OR
operators
single code['] need for string variables to compare.
here u get data-row, all cell will in an array format you select any cell.
You can try to use DefaultView.RowFilter property of DataTable class.
Example:
dataTable.DefaultView.RowFilter = "Account_number=1";

Categories

Resources