I have a dataset with one datatable, one row and six columns:
DataSet holdall = new DataSet();
holdone.Fill(holdall);
DataTable invoiceTable = holdall.Tables["INVOICE"];
The data comes from an SQL database, and consists of several different data types. I need to pass this data into an array or a list (AFAIK An array is more appropriate), and on the way convert it into string format:
string[] currentInvoice = new string[6];
currentInvoice = invoiceTable.AsEnumerable().Take(1).ToString().ToArray();
This gives me the following error:
Cannot implicitly convert type 'char[]' to 'string[]'
I have also tried
foreach (DataRow INVOICE in invoiceTable.AsEnumerable())
{
currentInvoice.ToArray();
}
However, this returns a Null exception, that leads be to believe that there is no data in the datatable. Upon examining the datatable via a stop point, I find that there is the correct amount of data.
Am I overcomplicating this?
When you call .ToString() you're converting whatever that is to a single string. Calling .ToArray() on a single string doesn't split that string into any meaningful substrings, it just converts it to a char[], which as the error states is incompatible with the variable type string[].
So, if I understand correctly... You have a table, of which you want only the first row, and you want the items in that row to be strings in an array? Something like this ought to work:
currentInvoice = invoiceTable.AsEnumerable().First().ItemArray.Select(i => i.ToString()).ToArray();
It takes the table as an enumerable, grabs the first row, looks at the array of items in that row, converts each item to a string, and converts that enumeration of strings into an array.
Edit: Note the use of .First() instead of .Take(1). While conceptually they do the same thing, .Take() returns a collection of items (even if there's only one item in the collection) whereas .First() returns only a single item. Note also that these could throw errors if there are no items in the collection from which you try to extract the first element. So you might want to add some error checking to ensure the table has rows before trying to extract the first row, if there could be a situation where it doesn't have rows.
Related
I have a method in which Sql stored procedure is executed taking values from Datagridview cells.This part of code is in Try Catch block.
What I need is to get all SP output values and other information from Datagridview cells to array or list, and after all rows have been processed to create a datatable and to use it as datasource for another Datagridview.
Can you please suggest how I can take values from Try block? And which one is recommended to use in this situation: list or array?
You might simply return the result object from inside the try-block. It's totally valid to have a return-command inside a try catch.
List or Array depends on whether you know the amount of elements before creating the list or array. Since you don't need the result list outside the method (and so you can assume that nobody else needs to add elements to it) using an array might save you a fraction of a second in processing time - but the list implementation of .net uses an array behind the scenes, so when you can call the constructor with a parameter of type int for the expected amount of elements, the overhead of a lisst is far less than calling the SP - so you can simply use the type you like.
For example, if each row of the data table holds information about an employee, one column might hold a string for their names, one column might hold a string for their phone numbers, and one column might be for their tasks. If an employee has multiple tasks, how can I store an array of strings that represents each task in that particular data cell?
You could use string.Join() on your array, and specify the delimiter to use between each array entry.
When you read it back out you can then split it back into an array.
Here is a quick and dirty bit of code that shows how to do it:
var tasks = new[] {"Boss", "Secretary", "Tea Lady"};
var joined = string.Join(", ", tasks);
var splitAgain = joined.Split(new[]{", "}, StringSplitOptions.RemoveEmptyEntries);
If you really need to use DataTable I would either combine multiple DataTables into a DataSet... or store this in xml format in a column
I iterate a DataTable's rows using -
DataTable dt = getDataTableFromSomeWhere();
DataRow row = null;
//for loop
row = dt.Rows[i];
How do I get the value of a column of the i-th row, by using the name of the column ?
I can iterate the columns using dt.Columns[j], but thats not what I want.
Just use the indexer taking a string parameter:
object value = row["ColumnName"];
EDIT: Assuming the value has been fetched in an appropriate type, I'd normally just cast to the CLR type you want:
int someIntegerValue = (int) row["ColumnName"];
Sometimes you may need two levels of casting (one to unbox and then another to perform an actual value conversion) but it depends on what you need.
I would recommend against converting to a string representation and then parsing that, unless you've really got no alternative. Excessive string conversions not only harm performance (usually not relevant) but they lead to sloppy type choices.
string name = (string) row["ColumnName"];
or
int i = Convert.ToInt32( row["ColumnName"]);
referencing by name is tiny bit slower but way more readable.
In C#, which one is more efficient way of reading reader object, through integer indexes or through named indexes ?
ad.Name = reader.GetString(0);
OR
ad.Name = reader["Name"].ToString();
The name overload needs to find the index first.
MSDN
a case-sensitive lookup is performed first. If it fails, a second
case-insensitive search is made (a case-insensitive comparison is done
using the database collation). Unexpected results can occur when
comparisons are affected by culture-specific casing rules. For
example, in Turkish, the following example yields the wrong results
because the file system in Turkish does not use linguistic casing
rules for the letter 'i' in "file".
From Getordinal (which is used therefore):
Because ordinal-based lookups are more efficient than named lookups,
it is inefficient to call GetOrdinal within a loop. Save time by
calling GetOrdinal once and assigning the results to an integer
variable for use within the loop.
so in a loop it might be more efficient to lookup the ordinal index once and reuse that in the loop body.
However, the name-lookup is backed by a class that is using a HashTable which is very efficient.
reader.GetString(index);
This will get the row value at that column index as string, The second solution is more ideal because it allows you to get the value at that index in your own prefered type.
Example:-
String name = reader["Name"].ToString();
int age = (int) reader["Age"]
ad.Name = reader["Name"].ToString();
This is most efficient way.
Because although you change database table structure afterwords, there will be no effect on this code since you have directly mentioned column name.
But with column index, it will change when you add any column to table before this column.
In asp.net I'm inserting array values into a database but array elements are not inserted properly. Instead of that, System.String[] is inserted.
SQL does not do arrays well. You have mostly likely just done a .ToString() on the array of strings.
Try using string.Join( ", ", mystrings).
As mentioned in the comments, this is not third normal form. Search wikipedia for a good synopsis.
System.String[] in the database implies that you are passing the string array directly to your database insert method.
Instead, you'll need to loop through the array and insert the strings as individual rows:
foreach(string s in stringArray)
{
database.Insert(s);
}
Alternatively, you can flatten the array and insert into a single row like this:
database.Insert(String.Join(",", stringArray))
This would insert the array as a comma-delimited list.