XML to database and vice-versa - c#

I can insert my XML easily into my database table, but i follow this exhausting manner as seen in my down code using LINK, which is perfectly tested. But, I wonder if I can find a way to read all my XML descendants elements of "Level" node, using iteration of all child tagnames, because when I make any change to my XML file, I would have to change my LINK code once again,and usually i'll face some errors when i use this exhausting manner. Please help improve this code:
try
{
XElement d = XElement.Parse(richTextBox1.Text.ToString());
var people = (from Level in d.Descendants("Level")
select new
{
ID = Convert.ToInt32(Level.Element("ID").Value),
Day1 = Level.Element("Day1").Value,
Day2 = Level.Element("Day2").Value,
Day3 = Level.Element("Day3").Value,
Day4 = Level.Element("Day4").Value,
Day5 = Level.Element("Day5").Value,
Day6 = Level.Element("Day6").Value,
Day7 = Level.Element("Day7").Value
}).ToList();
foreach (var item in people)
{
//Insert and Update
datacommand1.CommandText = "Insert Into MyTable(ID,Day1,Day2,Day3,Day4,Day5,Day6,Day7) values(" + item.ID + "," + "','" + item.Day1 + "','" + item.Day2 + "','" + item.Day3 + "','" + item.Day4 + "','" + item.Day5 + "','" + item.Day6 + "','" + item.Day7 + "')";
datacommand1.ExecuteNonQuery();
}
}
my XML file seems like that:
<level>
<id> 101 </id>
<Day1> task 1</Day1>
<Day2> task 2</Day2>
<Day3> task 3</Day3>
<Day4> task 4</Day4>
<Day5> task 5</Day5>
<Day6> task 6</Day6>
<Day7> task7 </Day7>
</level>

Instead of declaring one variable for each tag in the file, you may want to try to iterate over all them, extracting the name and the value for each one and composing the SQL statement at runtime from those, no matter what they are. Try something like this:
IEnumerable<XElement> items = d.Descendants("level").Elements();
string names = string.Empty;
string values = string.Empty;
foreach (XElement item in items)
{
names += item.Name + ",";
values += "#" + item.Name + ",";
IDbDataParameter parameter = datacommand1.CreateParameter();
parameter.ParameterName = "#" + item.Name;
parameter.DbType = DbType.String;
parameter.Value = item.Value;
datacommand1.Parameters.Add(parameter);
}
datacommand1.CommandText = "INSERT INTO MyTable (" + names.Substring(names.Length - 1) + ") VALUES (" + values.Substring(values.Length - 1) + ");";
datacommand1.ExecuteNonQuery();
This builds the command on the fly, based on the XML structure, and fills its parameters with the data there. But doing so relies on the fact that the table structure will be exactly the same as in the file, and still needs manual schema updating when the structure changes, but as long as they're in sync it should be fine.
EDIT
About datatypes, there are 2 choices I can think of. Leave as it is, sending everything as strings no matter what, and rely on the DB engine to parse, validate and turn those into numbers (depending on what DB you're using, that may be possible or not, but I guess it's not rare to see). Or modify the code to separate the special fields apart from the loop (and excluding from it) and add those one by one, specifying their types accordingly. This is easy to do if the numeric columns are fixed, like the ID, and everything else is text.

Related

using foreach to access a list

I am using a foreach loop to access the values of objects(of type Meal) stored in a list. Then I am calling a database query to save these values into the database .
This is the code I'm using :
foreach (Meal ml in mVals)
{
mID = ml.mealID;
MessageBox.Show(Convert.ToString(mID));
string oString2 = " INSERT into [dbo].[OrderMeal] (orderId,mealId,quantity) " + " VALUES ('" + orderId + "','" + mID + "','" + Convert.ToInt32(quant.Text) + "') ;";
SqlCommand oCmd2 = new SqlCommand(oString2, myConnection);
oCmd2.ExecuteNonQuery();
}
However, this only works for the last value in the list. The next loop iteration seems to be doing the same function, thereby saving the same record, giving an
error of violating the primary key constraint .
Is there some error in the way I am looping through the List?
What the structure of OrderMeal table?
Probably you have primary key in your table, and you need to vetify that you don't duplicate him.
try to enter the value in the list from the sql management.
verify that you don't have special characters in each item in the list( like comma and Apostrophe).
I think you can concatenate a set of insert statement and then ExcuteNonQuery for better performance.

Update database with date format

I found some threads here in the forum related to this problem but they didn't help me. I just want to update my database with a date value. These come from a Textfile (written there as 2014-10-02 for example). Now I tried this (which was mentioned in the other threads):
String connectionQuery = form1.conString.Text;
SqlConnection connection = new SqlConnection(connectionQuery);
SqlCommand sqlComInsert = new SqlCommand(#"INSERT INTO [" + form1.tableName.Text + "] ([" + form1.CusId.Text + "],["+ form1.date.Text +"],[" + form1.cusName.Text + "]) VALUES('" + cusId[i] + "',convert(date,'" + date[i] + "',104),'" + "','" + cusName[i] + "')", connection);
sqlComInsert.Connection.Open();
sqlComInsert.ExecuteNonQuery();
sqlComInsert.Connection.Close();
Now when I leave the "'" out ("',convert / "',104)) he tells me that the syntax is incorrect near 2013 (the beginning of my date). When I write it like above then I get:
String or binary data would be truncated.
What is this? I tried also to convert the date with:
for (int i = 0; i < typeDelDate.Count; i++)
{
unFormatedDate = date[i];
formatedDate = unFormatedDate.ToString("dd/MM/yyyy");
dateFormat.Add(formatedDate);
}
but I get still the same errors. How can I update my values? the column type is "date".
Use parametrized queries instead of slapping strings together:
var commandText = "insert (column) values (#dt);";
var cmd = new SqlCommand(commandText, connection);
cmd.Parameters.AddWithValue("dt", DateTime.ParseExact(dateString, "yyyy-MM-dd"));
cmd.ExecuteNonQuery();
Do not pass values into queries by adding strings - if possible, you should always use parameters. It saves you a lot of trouble converting to proper values (different for different locales etc.), it's more secure, and it helps performance.

Update DATETIME column where said DATETIME < current DATETIME

I've got an ASP.NET 4.0 C# web application that allows multiple users to update rows in the SQL Server DB at the same time. I'm trying to come up with a quick system that will stop USER1 from updating a row that USER2 updated since USER1's last page refresh.
The problem I'm having is that my web application always updates the row, even when I think it shouldn't. But when I manually run the query it only updates when I think it should.
This is my SQL query in C#:
SQLString = "update statuses set stat = '" + UpdaterDD.SelectedValue +
"', tester = '" + Session["Username"].ToString() +
"', timestamp_m = '" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") +
"' where id IN (" + IDs + ") and timestamp_m < '" + PageLoadTime + "';";
And here's a 'real world' example:
SQLString = "update statuses set stat = 'PASS', tester = 'tester007',
timestamp_m = '2013-01-23 14:20:07.221' where id IN (122645) and
timestamp_m < '2013-01-23 14:20:06.164';"
My idea was that this will only update if no other user has changed this row since the user last loaded the page. I have formatted PageLoadTime to the same formatting as my SQL Server DB, as you can see with DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), but something still isn't right.
Does anyone know why I get two different results? Is what I want to do even possible?
I really think the problem is that the page load time is not being set correctly, or is being set immediately before the DB call. For debugging, you may try hardcoding values into it that you know will allow or disallow the insert.
Here's a parameterized version of what you have. I also am letting the DB server set the timestamp to its current time instead of passing a value. If your DB server and your Web server may not have their time of day in synch, then set it yourself.
Using parameterization, you don't have to worry about whether the date/time format is correct or not. I don't know what the DB types are of stat, tester, and timestamp_m so adding the parameter DB type may need adjusting.
string sql = "update statuses set stat = #stat, tester = #tester" +
", timestamp_m = getdate()" +
" where id IN (" + IDs + ") and timestamp_m < #pageLoadTime";
SQLConnection conn = getMeASqlConnection();
SQLCommand cmd = new SQLCommand(sql, conn);
cmd.Parameters.Add("#stat", System.Data.SqlDbType.NVarChar).Value = UpdaterDD.SelectedValue;
cmd.Parameters.Add("#tester", System.Data.SqlDbType.NVarChar).Value = Session["Username"].ToString();
// Here, pageLoadTime is a DateTime object, not a string
cmd.Parameters.Add("#pageLoadTime", System.Data.SqlDbType.DateTime).Value = pageLoadTime;

LINQ to SQL custom query builder

It was easy to build a custom query like this with ADO.NET:
SqlCommand.CommandText = "SELECT Column" + variable1 + ", Column" + Variable2 + " FROM TABLE";
Is that able to do so in LINQ to SQL?
Thanks
No there is no common way to build a dynamic query.
A method has to have a known, specific return type. That type can be
System.Object but then you have to use a lot of ugly reflection code
to actually get the members. And in this case you'd also have to use a
lot of ugly reflection expression tree code to generate the return
value.
If you're trying to dynamically generate the columns on the UI side -
stop doing that. Define the columns at design time, then simply
show/hide the columns you actually need/want the user to see. Have
your query return all of the columns that might be visible.
Unless you're noticing a serious performance problem selecting all of
the data columns (in which case, you probably have non-covering index
issues at the database level) then you will be far better off with
this approach. It's perfectly fine to generate predicates and sort
orders dynamically but you really don't want to do this with the
output list.
More about this
Yes You can do something like that with Dynamic query with Linq.
This is an example that you can build a custom query with Dynamic query with Linq:
string strWhere = string.Empty;
string strOrderBy = string.Empty;
if (!string.IsNullOrEmpty(txtAddress.Text))
strWhere = "Address.StartsWith(\"" + txtAddress.Text + "\")";
if (!string.IsNullOrEmpty(txtEmpId.Text))
{
if(!string.IsNullOrEmpty(strWhere ))
strWhere = " And ";
strWhere = "Id = " + txtEmpId.Text;
}
if (!string.IsNullOrEmpty(txtDesc.Text))
{
if (!string.IsNullOrEmpty(strWhere))
strWhere = " And ";
strWhere = "Desc.StartsWith(\"" + txtDesc.Text + "\")";
}
if (!string.IsNullOrEmpty(txtName.Text))
{
if (!string.IsNullOrEmpty(strWhere))
strWhere = " And ";
strWhere = "Name.StartsWith(\"" + txtName.Text + "\")";
}
EmployeeDataContext edb = new EmployeeDataContext();
var emp = edb.Employees.Where(strWhere);
grdEmployee.DataSource = emp.ToList();
grdEmployee.DataBind();
For more information you can check this page.

% characters unexpectedly added in the middle of filename or folder name

I have web search form, When i submit my search in the search box,
The result are returned but with contains % in the file name.
for example. the original file name is abc.jpeg, so the result returned will be a%bc.
or if a folder is found with, so its the same for the folder name.
if a folder name is jack, in the result it will be ja%ck.
I have the text box (as a search box, and i have set the value of the search text box as) <%search text%>
Thanks for the help and taking time to read it.
I am using Asp.net, C# and Access DB.
code :
iscBuilder.AddSelect("* ");
iscBuilder.AddFrom("[table1] ");
iscBuilder.AddWhereClause("( column_name like('%" + pQuery + "%') or column_name like('%" + pQuery + "%') or column_name like('" + pQuery + "%') or column_name like('" + pQuery + "%') )");
iscBuilder.AddWhereClause("(column_name like( '" + path + "') or column_name like( '" + path + "')) order by column_name");
OleDbConnection sqlconConnection = (OleDbConnection)DatabaseConnection.Instance.GetConnection();
OleDbCommand sqlcmdCommand1 = new OleDbCommand(iscBuilder.ToString(), sqlconConnection);
sqlcmdCommand1.CommandType = CommandType.Text;
This is how i call the function: public XmlDocument GetSearchResults(string pQuery, string path,int from , int to)
{
List <T> ts= T.GetF().Getresult(pQuery, path);
return createXMLThumnails(thmbNails,from , to);
}
Have nice day
Try using a parameterised query or stored procedure to get your data - all this joining strings to make SQL statements is very fiddly and problematic.
Have a look at using Parameterised Queries or Stored Procedures.

Categories