Convert string to guid in DataColumn - c#

How do you convert a DataColumn of GUIDs set as type string to a DataColumn of GUIDs where the type is Guid? A column in the source data has the wrong type and I cannot change it there.

Once the datatable has been populated with data, you can't change the column type. There's a few approaches you can take:
If you're using a DataAdapter to fill the table, you can use DataAdapter.FillSchema() to get the structure of the table first. Then you can modify the column type, and then fill it with data.
Take the initial table and clone it, change the column type on the new table, and then use DataTable.ImportRow() to import each row from the old table.
Create a new column, copy the values from the old column to the new column, and delete the old column.

You can add to womp's answer the following option:
After you get the table full of the data you can add a new DataColumn to the Columns of the data table this way:
DataColumn dc = new DataColumn("GUIDColumnName",typeof(Guid),"StringColumnName");
DataTableObj.Columns.Add(dc);
This will not have a performance hit if your data volume is huge.

Related

User defined table type with dynamic columns in SQL Server

In my .NET (C#) win application, I import an Excel file that contains multiple columns of varying numbers. So, I store the data in my datatable in code and I need to pass that datatable to a SQL Server stored procedure for further processing.
Is there any proper way to pass my datatable to a SQL Server stored procedure and can user defined table type have a dynamic number of columns?
if it's possible to create a table type with a dynamic number of
columns.
No, its not possible.
My suggestion would be you can update the data from datatable directly to sql server table like this, then use the table in your procedure.
using (var bulkCopy = new SqlBulkCopy(_connection.ConnectionString, SqlBulkCopyOptions.KeepIdentity))
{
// my DataTable column names match my SQL Column names, so I simply made this loop. However if your column names don't match, just pass in which datatable name matches the SQL column name in Column Mappings
foreach (DataColumn col in table.Columns)
{
bulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName);
}
bulkCopy.BulkCopyTimeout = 600;
bulkCopy.DestinationTableName = destinationTableName;
bulkCopy.WriteToServer(table);
}
Note, datatable column name should be same as your sql table column name to get it mapped properly.
First of all, you can not create a table with a dynamic number of
columns.
You can use JSON to store all your borrowers in a single column. You really don't need to create multiple columns for borrowers. You can simply create a column in a table that will be of size NVARCHAR(MAX) and you have to create a JSON of all borrowers and store it in a table.
While retrieving data from the table deserialize it to get in original form.

Delete rows from DataTable at once without loop where a column has Null value

I'm populating a DataTable object from an Excel worksheet. I'm not counting on the user entering data correctly, and I'd like to delete rows that have a null value in column A. I've searched around quite a bit, and it looks like everyone is doing this with a for loop. Here's the problem: 757,000 rows. If data is not formatted properly that DataTable gets filled up with Excel's max of 1048575. I don't need to check each value individually. In SQL server you can write:
DELETE table
WHERE columnA IS NULL
I considered excluding nulls on the DataTable fill, but I couldn't get this to work reliably as I don't know the name of column A until it's in the DataTable and sometimes the column name has a \n character in the middle which throws syntax errors.
How can I accomplish the same sort of thing without a loop?
How about creating a new, clean DataTable from your first one?
DataTable t = new DataTable(); //actually your existing one with bad records
DataTable newTable = t.Select().Where(x => !x.IsNull(0)).CopyToDataTable();
Just use Linq...
var newData = (from d in DataTable //this would be your datatable.
where d.columnA != NULL
select d.*).CopyToDataTable<DataRow>();
Then just use your newData variable, which holds your newly populated datatable.

Getting the error "Column does not allow nulls"

I'm applying ADO.net and want to add a new row to a DataTable placed in a DataSet. I then try to update the database with the new row by using the update method of a DataAdapter. The error I'm getting is
Column "RECORD_ID does not allow nulls.
RECORD_ID is the primary key column of my source table which has an autonumber datatype. I'm using MS Access 2007. Any ideas anyone how to solve this avoiding hacks?
Column RECORD_ID is primary key, that means it should have unique values different from null every time. You are adding dataRow to DataSet but forget to set the row["Record_ID"].
You need something like that:
row["RECORD_ID"]= Guid.NewGuid();//if RECORD_ID is type of GUID
row["RECORD_ID"]= LastUniqueID+1; // if RECORD_ID is int.

How to get Dataset with specific Value in ASP.net?

I have a Data-set which has some columns.There is one Column named Is_Deleted which has a bool value.
I am retrieving a full Dataset using ado.net Code in WCF Service from SQL Server.
Now I want all the rows in the Dataset which has the Is_Deleted Column value = false.
Initially I was getting the desired result where Stored Procedure itself. Where I was selecting Columns where Is_deleted = false.
i want this Same operation to be done in C#.
So please tell me how can I proceed.
If you want to filter the DataSet/DataTable you can use Linq-To-DataSet:
var nonDeletedRows = ds.Tables[0].AsEnumerable()
.Where(row => !row.Field<bool>("Is_Deleted"));
If you need to persist this query you could create a new DataTable via CopyToDataTable:
DataTable tableWithNonDeletedRows = nonDeletedRows.CopyToDataTable();
If the DataSet is strongly typed you can use the auto-generated column directly.
For example (assuming the table-name is "TableName"):
tableWithNonDeletedRows = ds.TableName.Where(r=> !r.Is_Deleted).CopyToDataTable();

C# SqlBulkCopy types mismatch

I have a DataTable which has 10 columns, and after I add some rows in it, I want to add it to the database using SqlBulkCopy.
My problem is that in the DataTable I have strings and some fields in the database are decimal and date respectively. Is there a way to convert them to the desired data types?
When programmatically adding columns to your DataTable, you can specify type:-
DataTable dt = new DataTable();
dt.Columns.Add("FieldName", typeof(System.Decimal));
These will be honored when you perform the bulk copy.
EDIT
In response to user comment.
When populating the DataRow with information, an explicit conversion is only required if the source data doesn't match the target field.
If the types are the same, you can just assign it.
e.g.
// With a decimal field, decimal target
Decimal myNum = 123;
// Works fine - assuming the Price datacolumn has been set up as a System.Decimal
row["Price"] = myNum;
Sounds like you may be creating the columns in the DataTable in code (as opposed to Filling via a DataAdapter which would set the column data types appropriately).
If that's the case, then can you not just create the DataColumns with the correct data types to start with, instead of all strings...and then ensure when you add rows to it, you convert the data into the appropriate type?
i.e. get to the point where your DataTable has the correct types and data in correctly, so SqlBulkCopy can then blast it into the DB with data already in the correct form.
was having the same problem where in I was suppose to copy data from an excel file which had strings and I wanted them to be stored in the database as double. I have pasted the code related to the question below :-
DataTable dt = new DataTable();
//Read Data from First Sheet
connExcel.Open();
cmdExcel.CommandText = "SELECT * From [" + SheetName + "] ";
oda.SelectCommand = cmdExcel;
oda.Fill(dt);
connExcel.Close();
Convert.ToDouble(dt.Columns["Product"]);
//where product(product temperature) is the a column whose datatype in the database is float and in the excel file is string.

Categories