Search rows in Datatable with string a fast - c#

I need to select rows from with a string of IDs that are not the PK and int value x,
and datatable.select() takes to much time. Is there faster way to select them.
this is my code:
String a = "Id1, id2, ...";
meldunng.Select("columnname1 = " + 2 " AND columnname2 IN (" + a + ")")
If my question is confusing or I have worded it wrong please tell me.
Thanks in andvance

You could use a HashSet<string> to improve performance and LINQ for the query:
var ids = new HashSet<string>(new[] {"Id1", "id2", "id3"}, StringComparer.OrdinalIgnoreCase); // i guess you want to ignore the case
var matchingRows = meldunng.AsEnumerable()
.Where(row => row.Field<int>("columnname1") == 2 && ids.Contains(row.Field<string>("columnname2")));
Note that this is just the LINQ query and you need to "materialize" it to something, for example a DataRow[]:
DataRow[] resultRows = matchingRows.ToArray();

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();

Linq to SQL JOIN?

I am trying to query names in one table and then use that result to pull the master records into a DataGridView. So what I need to do is get the names from the interest table that are like what is put into text boxes then use those results to pull the data from the CaseSelector table and set the bindingsource filter to those results. Why can't I seem to set results to the caseSelectorBindingSourceFilter
var results = from CaseSelector in db.CaseSelectors
from Interest in db.Interests
where SqlMethods.Like(Interest.First, txtFirst.Text) && SqlMethods.Like(Interest.Last, txtLast.Text)
select CaseSelector;
caseSelectorBindingSource.Filter = ("CaseNumberKey =" + results);
You can find examples for LINQ join queries here:
http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b
I don't know your DB schema but you're looking for something along the lines of:
from c in db.Cases
join i in db.Interest on i.CaseNumberKey equals c.CaseNumberKey
select c
What you've just retrieved is a SQL Set of the valid caseNumberKeys.
Your casefilter should be something like
caseSelectorBindingSource.Filter = "CaseNumberKey in " + interestsresultsAsSQLSET;
You'll have to iterate over the interestsresults and convert it to the string representation of a SQLSET. If you're feeling lucky, you could just try to .toString() it and see what happens.
string interestsResultsAsSQLSet = "(";
//write most of them
for(int i=0; i<interestsresults.size() - 1; i++) {
interestsResultAsSQLSet.append(interestsresults[i] + ",");
//write the last one, with right paren
interestsresults.append(interestsresults[interestsresults.size() -1] + ")");
I write Java all day, ignore my basic language errors. :P

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);
}

Extract only values from insert statement string?

This may seem strange at first but I hope it makes sense! I have a list<string> of mysql insert statements that I iterate through and execute on a one by one basis, this works ok but what I am trying to achieve is a performance boost.
I would like to pass all the values in a single query for example instead of
INSERT INTO tb1(field1,field2,field3) VALUES (1,2,3);
INSERT INTO tb1(field1,field2,field3) VALUES (4,5,6);
INSERT INTO tb1(field1,field2,field3) VALUES (7,8,9);
I would like to do
INSERT INTO tb1(field1,field2,field3) VALUES (1,2,3), (4,5,6), (7,8,9);
so basically I need to build a long query string keeping the first query as a starting point and appending the bracket section from values to the end for whatever the count of objects in the list may be - is this possible?
This should work. I'm using regex to find the columns and values and string.Substring to find the table-name. Then i put all together with string.Format and string.Join and a simple Linq query:
IEnumerable<string> inserts = // add your insert-strings here;
string firstInsert = inserts.First();
int tableIndex = firstInsert.IndexOf("INSERT INTO ") + "INSERT INTO ".Length;
string table = firstInsert.Substring(
tableIndex, firstInsert.IndexOf("(", tableIndex) - tableIndex);
var regex = new System.Text.RegularExpressions.Regex(#"\(([^)]+)\)",System.Text.RegularExpressions.RegexOptions.Compiled);
string columns = regex.Matches(firstInsert)[0].Value;
IEnumerable<string> values = inserts.Select(sql => regex.Matches(sql)[1].Value);
string insertAll = string.Format("INSERT INTO {0}{1} VALUES {2};"
, table
, columns
, string.Join(",", values));
DEMO with your sample data.
Just in case you might be inserting to different tables (or sets of columns within tables),
var perTableQueries = separateQueries
.Select(s => s.Split(new[] {" VALUES "}, StringSplitOptions.None))
.Where(a => a.Length == 2)
.GroupBy(a => a[0], StringComparer.InvariantCultureIgnoreCase)
.Select(g => String.Format("{0} VALUES {1};",
g.Key,
String.Join(",", g.Select(a => a[1].TrimEnd(';')).ToArray())));
will make a single insert per table/column set (if your SQL is consistent).
That said, if you're making a separate request to the database for each line, your biggest performance saving might just be
var singleRequest = String.Join("", perTableQueries.ToArray());

Having trouble trying to implement a query on dataset/datatable

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();

Categories

Resources