c# loop within a loop - c#

I'm currently using DataSets to bring back results in a C# service which I now need to change to loop through the initial set of data and bring back a subset of data from this result.
So I need to loop through these results using an identifier and then show another set of results within a nest below each of these. Using datasets seems no way of making this happen from my limited C# knowledge.
EG> Loop through DB, for each result in DB loop through another table.
[WebMethod(BufferResponse=true,Description="Viewing Things")]
public DataSet MyFunctionIs (int IDtoQuery)
{
MySqlConnection dbConnection = new MySqlConnection("server=na;uid=na;pwd=na;database=na;");
MySqlDataAdapter objCommand = new MySqlDataAdapter("SELECT STATEMENT HERE;", dbConnection);
DataSet DS = new DataSet();
objCommand.Fill(DS,"MyFunctionIs");
}
But even using joins isnt going to fulfill.. I need to query of each row returned on this and return a child set of data for the XML response

Often you can solve this kind of problem by using a SQL query that joins several tables and returns only one set of rows. This gives you a general idea on how you can try to do it:
string ConnectionString = "server=myserver;uid=sa;pwd=secret;database=mydatabase";
using (var con = new SqlConnection(ConnectionString)) {
string CommandText = "SELECT p.firstname, p.lastname, o.operderdate " +
"FROM persons p LEFT JOIN orders o ON p.person_id = o.person_id";
using (var cmd = new SqlCommand(CommandText, con)) {
con.Open();
using (var reader = cmd.ExecuteReader()) {
while (reader.Read()) {
Console.WriteLine("{0} {1}, {2}", reader["firstname"], reader["lastname"], reader["operderdate"]);
}
}
}
}

Related

SQLServer:How to speed up Select and Insert query in loops of statements using c#

I am trying to insert into table from array of Json as well as select records from SQL Server DB table.
When executing the below method it is almost taking more than 10 minutes.
public async Task CreateTableAsync(string formsJson, string connectionString)
{
SqlConnection con = new SqlConnection(connectionString);
List<FormsJson> listOfformsJson = JsonConvert.DeserializeObject<List<FormsJson>>(formsJson);
foreach (var form in listOfformsJson)
{
string formId = Guid.NewGuid().ToString();
//insert into forms Table
string formQuery = "insert into Forms([FormId]) values(#FormId)";
using (var cmd = new SqlCommand(formQuery, con))
{
cmd.CommandTimeout = 120;
//Pass values to Parameters
cmd.Parameters.AddWithValue("#FormId", formId);
if (con.State == System.Data.ConnectionState.Closed)
{
con.Open();
}
cmd.ExecuteNonQuery();
}
//relationship between forms and ETypes,get all the eTypes and fill
foreach (var typeOf in form.TypeOf)
{
//get all the eTypeIds for this typeof field
string query = "select Id from ETypes Where TypeOf = #typeOf";
List<string> eTypeIdList = new List<string>();
using (var sqlcmd = new SqlCommand(query, con))
{
sqlcmd.CommandTimeout = 120;
//Pass values to Parameters
sqlcmd.Parameters.AddWithValue("#typeOf", typeOf);
if (con.State == System.Data.ConnectionState.Closed)
{
con.Open();
}
SqlDataReader sqlDataReader = sqlcmd.ExecuteReader();
while (sqlDataReader.Read())
{
string eTypeId = sqlDataReader[0].ToString();
eTypeIdList.Add(eTypeId);
}
sqlDataReader.Close();
}
//insert into Forms ETypes Relationship
string fe_query = "";
foreach (var eTypeId in eTypeIdList)
{
fe_query = "insert into Forms_ETypes([Form_Id],[EType_Id]) values (#Form_Id,#EType_Id)";
if (con.State == System.Data.ConnectionState.Closed)
{
con.Open();
}
using (var fesqlcmd = new SqlCommand(fe_query, con))
{
fesqlcmd.CommandTimeout = 120;
//Pass values to Parameters
fesqlcmd.Parameters.AddWithValue("#Form_Id", formId);
fesqlcmd.Parameters.AddWithValue("#EType_Id", eTypeId);
fesqlcmd.ExecuteNonQuery();
}
}
}
}
}
Outer foreach(...listofformsJson) loop more than hundreds of records.
And same for the inner loop around hundreds of rows.
In between commandTimeout, keeping the open connection with server statements.
Any help to optimize the time and remove/add ADO statements.
The primary issue here is that you are pulling all of the data out of the database and then, row by row, inserting it back in. This is not optimal from the database's point of view. It is great at dealing with sets - but you are treating the set as lots of individual rows. Thus it becomes slow.
From a set-based standpoint, you have only two statements that you need to run:
Insert the Forms row
Insert the Forms_ETypes rows (as a set, not one at a time)
1) should be what you have now:
insert into Forms([FormId]) values(#FormId)
2) should be something like:
insert Forms_ETypes([Form_Id],[EType_Id]) SELECT #FormId, Id from ETypes Where TypeOf IN ({0});
using this technique to pass in your form.TypeOf values. Note this assumes you have fewer than 500 entries in form.TypeOf. If you have many (e.g. greater than 500) then using a UDT is a better approach (note some info on UDTs suggest that you need to use a stored proc, but that isn't the case).
This will enable you to run just two SQL statements - the first, then the second (vs possibly thousands with your current solution).
This will save time for two reasons:
The database engine didn't need to pass the data over the wire twice (from your DB server to your application, and back again).
You enabled the database engine to do a large set based operation, rather than lots of smaller operations (with latency due to the request-response nature of the loop).

How to fetch only some rows from a SqlDataReader?

i'm fetching values from a table with datareader like this:
string query = #"SELECT XMLConfig, Enable FROM TableCfg";
using (SqlConnection cnction = new SqlConnection(cnnstr))
{
cnction.Open();
using (SqlCommand sqlCmd = new SqlCommand(query, cnction))
{
SqlDataReader dtRead = sqlCmd.ExecuteReader();
while (dtRead.Read())
{
xmlConf = dtRead.GetString(0);
enabl = dtRead.GetString(1);
}
dtRead.Close();
}
}
The Enable field is a boolean(True/False). Is there a way to fetch only the rows, where field enable="True"?
I tried using LINQ, but i'm new to this and i must be doing something wrong.
using (SqlCommand sqlCmd = new SqlCommand(query, cnction))
{
SqlDataReader dtRead = sqlCmd.ExecuteReader();
var ob =(from IDataRecord r in sqlCmd.ExecuteReader()
where r.GetString(3).ToString() == "True"
select "Enable");
}
Help me please.
Best Regards.
You should really do as much filtering as possible at the database side rather than client-side:
string query = "SELECT XMLConfig FROM TableCfg WHERE Enable = True";
Notice how now you don't even need to fetch Enable, as you already know it will be True for all the matching rows.
You should also consider using LINQ to SQL or Entity Framework rather than the rather low-level stack you're currently using. It's not always appropriate, but it does make things cleaner where it's suitable.

How can I insert/update rows with C# to SQL Server

I am quit busy turning a old classic asp website to a .NET site. also i am now using SQL Server.
Now I have some old code
strsql = "select * FROM tabel WHERE ID = " & strID & " AND userid = " & struserid
rs1.open strsql, strCon, 2, 3
if rs1.eof THEN
rs1.addnew
end if
if straantal <> 0 THEN
rs1("userid") = struserid
rs1("verlangid") = strID
rs1("aantal") = straantal
end if
rs1.update
rs1.close
I want to use this in SQL Server. The update way. How can I do this?
How can I check if the datareader is EOF/EOL
How can I insert a row id it is EOF/EOL
How can I update a row or delete a row with one function?
If you want to use raw SQL commands you can try something like this
using (SqlConnection cnn = new SqlConnection(_connectionString))
using (SqlCommand cmd = new SqlCommand())
{
cnn.Open();
cmd.Connection = cnn;
// Example of reading with SqlDataReader
cmd.CommandText = "select sql query here";
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
myList.Add((int)reader[0]);
}
}
// Example of updating row
cmd.CommandText = "update sql query here";
cmd.ExecuteNonQuery();
}
It depends on the method you use... Are you going to use Entity Framework and LINQ? Are you going to use a straight SQL Connection? I would highly recommend going down the EF route but a simple straight SQL snippet would look something like:
using (var connection = new SqlConnection("Your connection string here"))
{
connection.Open();
using (var command = new SqlCommand("SELECT * FROM xyz ETC", connection))
{
// Process results
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
int userId = (int)reader["UserID"];
string somethingElse = (string)reader["AnotherField"];
// Etc, etc...
}
}
}
// To execute a query (INSERT, UPDATE, DELETE etc)
using (var commandExec = new SqlCommand("DELETE * FROM xyz ETC", connection))
{
commandExec.ExecuteNonQuery();
}
}
You will note the various elements wrapped in using, that is because you need to release the memory / connection when you have finished. This should answer your question quickly but as others have suggested (including me) I would investigate Entity Framework as it is much more powerful but has a learning curve attached to it!
You can use SQL store procedure for Update. And call this store procedure through C#.
Create procedure [dbo].[xyz_Update]
(
#para1
#para2
)
AS
BEGIN
Update tablename
Set Fieldname1=#para1,
Set Feildname2=#para2
end

What is C# equivalent of PHP's mysql_fetch_array function?

I am learning C#/ASP.NET and I am wondering what the C# equivalent of the following PHP code is?
I know the userid, and I want to fetch the rows from this table into the array of the variable "row", so I then can use it as "row['name']" and "row['email'].
$result = mysql_query("SELECT email, name FROM mytable WHERE id=7");
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
printf("Email: %s Name: %s", $row["email"], $row["name"]);
}
Thanks.
I'm not sure if this is the same as mysql_fetch_array but i assume that.
You can use IDBCommmand.ExecuteReader to create an IDataReader and use that to fill an Object[] with all fields of the row.
For example (using SQL-Server):
// use using statements to ensure that connections are disposed/closed (all implementing IDisposable)
using (var con = new SqlConnection(Properties.Settings.Default.ConnectionString))
using (var cmd = new SqlCommand("SELECT email, name FROM mytable WHERE id=#id", con))
{
cmd.Parameters.AddWithValue("#id", ID); // use parameters to avoid sql-injection
con.Open();
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var fields = new object[reader.FieldCount];
// following fills an object[] with all fields of the current line,
// is this similar to mysql_fetch_array?
int count = reader.GetValues(fields);
}
}
}
Edit:
I don't mean to make it as similar as possible, but how would I go about getting the same end result (a variable with the results) in C#
That's a matter of taste. You could use some kind of ORM like Enity-Framework, NHibernate, LINQ-To-SQL or Stackoverflow's Micro-ORM Dapper.NET(what i'm using currently) or plain ADO.NET (as shown above).
You can use a custom class that you fill manually with a DataReader or a DataTable which schema is loaded automatically.
For example (here using MySQL):
DataTable tblEmail = new DataTable();
using (var con = new MySqlConnection(Properties.Settings.Default.MySQL))
using (var da = new MySqlDataAdapter("SELECT Email, Name FROM Email WHERE id=#id", con))
{
da.SelectCommand.Parameters.AddWithValue("#id", ID);
da.Fill(tblEmail);
}
if (tblEmail.Rows.Count == 1)
{
DataRow row = tblEmail.Rows[0];
String email = row.Field<String>("Email");
String name = row.Field<String>("Name");
}
As you can see, there are many ways in .NET. I have shown just two with ADO.NET.
There's no true equivalent. Having been a PHP developer in the past, I'd say the closest thing is to use a data adapter and fill a data table. Here's a reference to DbDataAdapter.Fill.
I'm not sure about the MySql driver but if you're using Sql Server here's some code to get you started:
using (var connection = new SqlConnection(connectionString))
{
var table = new DataTable("tbl_objects");
var adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand("SELECT * FROM tbl_name", connection);
adapter.Fill(table);
}
Then, you can iterate over the rows in the table:
foreach(var row in table)
{
Console.WriteLine("{0}", row["ColumnName"]);
}
You could loop through your result with a foreach loop as follows:
foreach(var row in result)
{
console.writeline("Email:" + row.Email, "Name:", row.Name);
}
Is that the sort of thing you were looking for?
EDIT
In fact i have just seen you only have one result.
Then you can skip the foreach loop altogether
You need a connection to a database.
Assuming you are using mysql and an odbc connection.
var connectionString = "DRIVER={MySQL ODBC 3.51 Driver};" +
"SERVER=localhost;" +
"DATABASE=test;" +
"UID=venu;" +
"PASSWORD=venu;" +
"OPTION=3");
using (OdbcConnection connection = new OdbcConnection(connectionString))
{
OdbcCommand command = new OdbcCommand("SELECT email, name FROM mytable WHERE id=7", connection);
connection.Open();
// Execute the DataReader and access the data.
OdbcDataReader reader = command.ExecuteReader();
while (reader.Read())
{
//do stuff with the data here row by row the reader is a cursor
}
// Call Close when done reading.
reader.Close();
alternately you could use an odbcdataadapter and a datatable if you wanted all the results in a table you could use like an array.
The closest equivalent in .net would be something like this...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MySql.Data.MySqlClient;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
var foo = MySqlHelper.ExecuteDataRow("Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;", "select * from foo");
Console.WriteLine(foo["Column"]);
}
}
}
I assume you are using the MySql Data Connector http://dev.mysql.com/downloads/connector/net/
Do note there are better ways available in .net to connect to databases, but I think for a line by line, this is about as close to the PHP as you can get.

C# Excel result comparation

I have never learned this aspect of programming, but is there a way to get each separate result of a excel query(using OleDB) or the likes.
The only way I can think of doing this is to use the INTO keyword in the SQL statement, but this does not work for me (SELECT attribute INTO variable FROM table).
An example would be to use the select statement to retrieve the ID of Clients, and then compare these ID's to clientID's in a client ListArray, and if they match, then the clientTotal orders should be compared.
Could someone prove some reading material and/or some example code for this problem.
Thank you.
This code fetches rows from a sql procedure. Will probably work for you too with some
modifications.
using (var Conn = new SqlConnection(ConnectString))
{
Conn.Open();
try
{
using (var cmd = new SqlCommand("THEPROCEDUREQUERY", Conn))
{
cmd.CommandType = CommandType.StoredProcedure;
SqlDataReader reader = cmd.ExecuteReader();
// Find Id of column in query only once at start
var Col1IdOrd = reader.GetOrdinal("ColumnName");
var Col2IdOrd = reader.GetOrdinal("ColumnName");
// loop through all the rows
while (reader.Read())
{
// get data for each row
var Col1 = reader.GetInt32(ColIdOrd);
var Col2 = reader.GetDouble(Col2IdOrd);
// Do something with data from one row for both columns here
}
}
}
finally
{
Conn.Close();
}

Categories