Changing database asp.net - c#

I am building a project on asp.net with sql database.
I want to update a row in the table.
the table name - parkingLots , the column I want to update is - "free spaces".
this is the code I wrote but it does'nt do the updating in the table:
var arduinoQuery1 = from b in db.parkingLots
where b.parkingLotID == 1
select b;
foreach (parkingLot b in arduinoQuery1)
{
b.freeSpaces = space;
}
I want to make free spaces of this specific row to be equal to "space".
How do I do that?

write
db.savechange()
in foreach loop

Related

Words are added to the end of a column

In my database, each letter has its own column, but when I add words to the column, it goes to the bottom and Null fields are created
Now so
And I need it this
I have a list of words and the word must fall into the column from which the first letter of the word begins
My Code
private void ConnectData()
{
_path = "URI=file:" + Application.streamingAssetsPath + "/russianWords.db"; //Path to datab
_dbConnection = new SqliteConnection(_path);
_dbConnection.Open();
if (_dbConnection.State == ConnectionState.Open)
{
m_sqlCmd = new SqliteCommand();
m_sqlCmd.Connection = _dbConnection;
m_sqlCmd.CommandText = "CREATE TABLE IF NOT EXISTS words (а Text , б Text ,в Text,г Text,д Text,е Text,ё Text,ж Text,з Text,и Text,й Text,к Text,л Text,м Text,н Text,о Text,п Text,р Text,с Text,т Text,у Text,ф Text,х Text,ц Text,ч Text,ш Text,щ Text,ъ Text,ы Text,ь Text,э Text,ю Text,я Text)";
m_sqlCmd.ExecuteNonQuery();
}
AddToData("sddd", "т");
}
public void AddToData(string word)
{
try
{
m_sqlCmd.CommandText = $#"INSERT INTO words ('{word.ToCharArray()[0].ToString()}') values ('{ word }')";
m_sqlCmd.ExecuteNonQuery();
}
catch (System.Exception e)
{
Debug.Log(e);
}
}
Databases don't work like this. Putting data in a table will always make a new row. It is not like a game of upwards- Tetris where you insert "Fred" into column "F" and it will find the first empty slot (nearest the "top") and put it there. There isn't even the sense of "top" - datatable tables are just a bunch of rows stored in whatever order the database feels like. If you want your data to have an order you must insert some data that has an order (like an int) and sort by it
If you want this "Tetris" style behavior you must program it explicitly. Have a column that is incrementing numbers
ID A B C
1
2
You want to insert Apple. Select the lowest ID where the column is blank
SELECT MIN(id) FROM t WHERE A IS NULL
ExecuteScalar that and cast the result to an int?
If there is an ID, update it. Otherwise insert:
UPDATE t SET A = 'Apple' WHERE ID = 1
ID A B C
1 Apple
2
Now we want to insert Aeroplane. It will go in ID 2 by the same logic
ID A B C
1 Apple
2 Aeroplane
Now we insert Aurora. There is no row 3. The SELECT that finds the ID will return no rows (you'll get a null returned from execute scalar)
Run the following insert
INSERT INTO t(ID, A)
SELECT MAX(id)+1, 'Aurora' FROM t
ID A B C
1 Apple
2 Aeroplane
3 Aurora
You now have aurora in ID 3
Continue thus either inserting or updating. You should thus have at least one column that is completely full all the time and the others will fill in as they go..
--
Consider to use any auto numbering facility your chosen db has rather than max+1 (but max+1 would work)

C# Merge two header columns into one column?

I use C#[2013] winform. I drag and drop a datagridview and design it in two cols then I select value from database to it. I now want to merge two headers into one only. The headers already displayed by designing in properties.
I want to merge the columns.
Col1 | Col2
001 | John
I want to merge into one col as
Title
001 | John
How to merge it?
What type of datasource are you binding to... You might just be better to add a new column to a datatable, or property to a class/structure that is a combined value of the two in question. Then just display that one.
If editing is done to any individual field, then update the JOINED column/property as needed.
In the class that you are using as the source for you DataGridView put a new property:
public string Title { get { return this.Col1 + " | " + this.Col2; }}
then delete those two columns and add one column for Title
Assuming you're talking about a DataGridView, there doesn't appear to be an easy built in-solution for this. Perhaps you could simply copy the data from one column to the other and split them with some sort of delimiter (perhaps a comma).
Modify then run following code after you fill your grid with data:
string data = string.Empty;
int indexCol0 = 0;
int indexCol1 = 1;
foreach (DataGridViewRow row in dataGridView1.Rows)
row.Cells[indexCol0].Value = row.Cells[indexCol0].Value + ", " + row.Cells[indexCol1].Value;
dataGridView1.Columns.RemoveAt(indexCol1);

Stored Proceedure or GridView DataSource

I've built a frontend to update an individual column for selected records in a GridView. I've gotten that all setup the way that I want it to work including performing a check to be sure that more than one row is selected (via a template field checkbox I added to the GridView) and that a column has been selected from a dropdown list.
I have everything down to the block of code that has to be built to do the actual update of the column for the selected rows. This will cycle through each row, so if I've selected 5 rows it would trigger this code 5 times and update the record ID associated with that row.
I'm mainly debating with myself which would be the simplest to build into this. I at first thought about doing a stored procedure on the SQL Server and feeding it the record ID, column to update, and the value to write in the update. But then I got to thinking about it and realized that I have a GridView with a Data Source that was already setup to update the record as long as I called it
In either case I'll need to refresh the GridView after the update has been completed.
Just wondering what others might think would be the cleanest approach to this and just what my options might be. I've never seen a multi row column edit implemented so figure someone may have a better idea than me on how to go about this.
Here is my code block for the update as it is right now...
protected void SaveColEditBtn_Click(object sender, EventArgs e)
{
//Read the column select drop down List into Local Varriables
String SelectedColumnItem = ColumnSelectDDL.SelectedItem.ToString();
String SelectedColumnValue = ColumnSelectDDL.SelectedValue.ToString();
List<int> EditRows = new List<int>();
List<string> recordnumber = new List<string>();
foreach (GridViewRow grv in ActVulListGV.Rows)
{
if (((CheckBox) grv.FindControl("TagRowChkBx")).Checked == true)
{
//get current row rowindex if checkbox in it is checked
EditRows.Add(grv.RowIndex);
//get the record number (RecID)
recordnumber.Add(grv.Cells[2].Text.ToString());
}
}
int[] ERows = EditRows.ToArray();
if (recordnumber.Count > 1)
{
if (ColumnSelectDDL.SelectedValue.ToString() == "TicketNumber")
{
// Save Ticket number //
}
else if (ColumnSelectDDL.SelectedValue.ToString() == "TicketClosed")
{
// Save Ticket Closed Value //
}
else if (ColumnSelectDDL.SelectedValue.ToString() == "Notes")
{
// Save Notes //
}
else if(ColumnSelectDDL.SelectedValue.ToString() == "Exception_ID")
{
// Save Exception ID //
}
EditColMsgLbl.Font.Bold = true;
SelectedRowsMsgLbl.Font.Bold = true;
ColEditPnlExt.Show();
EditColLbl.Text = SelectedColumnItem;
SelectedRowsLbl.Text = "";
foreach (string record in recordnumber)
{
// Insert the call of the procedure here to update the database
}
}
else
{
UserMessageLbl.Text = " *** Choose 2 or more rows to use column edit feature! ***";
mpePopUp.Show();
}
}
It depends. If you are updating all at once, by looping, use a Stored Procedure. However updating one by one with EditIndex, it is easier to use the source. However I would recommend using code behind and a SP to update a row, then you could use the same SP for updating a single or all rows.
See this excellent tutorial. It covers all the basics of GridView editing and updating.
And a tip if you have some time to spare in the near future, try to disable ViewState for the GridView. It will save a lot of tranfer kb's and overhead. But get the above to work first ;)

Optimizing query that uses AsEnumerable and SingleOrDefault

Not long ago there was a feature request in the program I am maintaining. Basically it has to fill up a table in the database with info from a text file. These files can be pretty big, but it was fairly easy to do because these files were defined as the complete list of user data. Therefore the table could be truncated and the just filled up again with data from the text file.
But then a week ago it was decided that these files are actually updates of current user info, so now I have to retrieve the correct MeteringPointId (which only exist once if it does exist) and then update info on it. If it doesn't exist, just insert data as before.
The way I do this is retrieving the complete database table with data from the database into memory and then just updating on that info before finally saving the changes by calling the datatables update function. It works fine, except that finding the row with the MeteringPointId is slow:
DataRow row = MeteringPointsDataTable.NewRow();
// this is called for each line in the text file to find the corresponding MeteringPointId. It can be 300.000 times.
row = MeteringPointsDataTable.AsEnumerable().SingleOrDefault(r => r.Field<string>("MeteringPointId").ToString() == MeteringPointId);
Is there a way to retrieve a DataRow from a DataTable that is faster than this?
If you are sure that only one item con fullfil the condition use FirstOrDefault instead of Single. Thus you won´t collect the whole table but only the first entry you´ve found.
You can use Select method of DataTable.
var expression = "[MeteringPointId] = '" + MeteringPointId + "'";
DataRow[] result = MeteringPointsDataTable.Select(expression);
Also you can create an expression like,
var idList = new []{"id1", "id2", "id3", ...};
var expression = "[MeteringPointId] in " + string.Format("({0})", string.Join(",", idList.Select(i=> "'"+i+"'")));
Similar usage is here
Hope it helps..
You could put the whole table in a dictionary:
//At the start
var meteringPoints = MeteringPointsDataTable.AsEnumerable().ToDictionary(r => r.Field<string>("MeteringPointId").ToString());
//For each row of the text file:
DataRow row;
if (!meteringPoints.TryGetValue(MeteringPointId, out row))
{
row = MeteringPointsDataTable.NewRow();
meteringPoints[MeteringPointId] = row;
}

What is the best way to fast insert SQL data and dependant rows?

I need to write some code to insert around 3 million rows of data.
At the same time I need to insert the same number of companion rows.
I.e. schema looks like this:
Item
- Id
- Title
Property
- Id
- FK_Item
- Value
My first attempt was something vaguely like this:
BaseDataContext db = new BaseDataContext();
foreach (var value in values)
{
Item i = new Item() { Title = value["title"]};
ItemProperty ip = new ItemProperty() { Item = i, Value = value["value"]};
db.Items.InsertOnSubmit(i);
db.ItemProperties.InsertOnSubmit(ip);
}
db.SubmitChanges();
Obviously this was terribly slow so I'm now using something like this:
BaseDataContext db = new BaseDataContext();
DataTable dt = new DataTable("Item");
dt.Columns.Add("Title", typeof(string));
foreach (var value in values)
{
DataRow item = dt.NewRow();
item["Title"] = value["title"];
dt.Rows.Add(item);
}
using (System.Data.SqlClient.SqlBulkCopy sb = new System.Data.SqlClient.SqlBulkCopy(db.Connection.ConnectionString))
{
sb.DestinationTableName = "dbo.Item";
sb.ColumnMappings.Add(new SqlBulkCopyColumnMapping("Title", "Title"));
sb.WriteToServer(dt);
}
But this doesn't allow me to add the corresponding 'Property' rows.
I'm thinking the best solution might be to add a Stored Procedure like this one that generically lets me do a bulk insert (or at least multiple inserts, but I can probably disable logging in the stored procedure somehow for performance) and then returns the corresponding ids.
Can anyone think of a better (i.e. more succinct, near equal performance) solution?
To combine the previous best two answers and add in the missing piece for the IDs:
1) Use BCP to Load the data into a temporary "staging" table defined like this
CREATE TABLE stage(Title AS VARCHAR(??), value AS {whatever});
and you'll need the appropriate index for performance later:
CREATE INDEX ix_stage ON stage(Title);
2) Use SQL INSERT to load the Item table:
INSERT INTO Item(Title) SELECT Title FROM stage;
3) Finally load the Property table by joining stage with Item:
INSERT INTO Property(FK_ItemID, Value)
SELECT id, Value
FROM stage
JOIN Item ON Item.Title = stage.Title
The best way to move that much data into SQL Server is bcp. Assuming that the data starts in some sort of file, you'll need to write a small script to funnel the data into the two tables. Alternately you could use bcp to funnel the data into a single table and then use an SP to INSERT the data into the two tables.
Bulk copy the data into a temporary table, and then call a stored proc that splits the data into the two tables you need to populate.
You can bulk copy in code as well, using the .NET SqlBulkCopy class.

Categories

Resources