Datatable column into a string with string.join - string

I have a datatable that contains a single column. I want to join all the rows in this datatable in to a single string with string.join
I used the following but it gives me the error best overloaded method for string.join(string, string[]) has some invalid arguments.
string s = string.Join(", ", ds.Tables[1].Rows.OfType<DataRow>().Select(r => r[0].ToString()));
Can someone help me with writing it correct?
I was referring to the following to get that code:
Store each DataTable Column in string var

Your code seams correct.
If you have a datatable with one column like this:
Test
====
123
456
And apply your code, you will get the string "123, 456"
// Init datatable
var dt = new DataTable();
dt.Columns.Add("Test");
dt.Rows.Add(dt.NewRow()["Test"] = "123");
dt.Rows.Add(dt.NewRow()["Test"] = "456");
// Join columns
string s = string.Join(", ", dt.Rows.OfType<DataRow>().Select(r => r[0].ToString()));

Related

Find distinct values from column of datatable in c# and store distinct values in variables

i want to find distinct values from a column of datatable in c# and also want to store all these distinct values in variables
DataTable dtable = new DataTable();
OleDbDataAdapter da = new OleDbDataAdapter("SELECT * from clubbb ", con);
da.Fill(dtable, "clubbb");
int toto = bdtable.AsEnumerable().Distinct().Count();
You need to implement the interface IEqualityComparer<DataRow> methods to provide the way the Distinct method will use to know whether 2 rows are duplicate or not. This can be achieved with a class like this:
public class CustomComparer : IEqualityComparer<DataRow>
{
public bool Equals(DataRow x, DataRow y)
{
// your custom equality logic here
}
public int GetHashCode(DataRow obj)
{
// return hash code depending on your distinct criteria
}
}
Then change the call you made:
int toto = bdtable.AsEnumerable().Distinct(new CustomComparer()).Count();
I had similar problem, and in my case I needed to know distinct values of specific column, so I passed the name of this column to the custom comparer I implemented, so that GetHashCode will return identical hash codes for duplicate values.
You can read more here: https://msdn.microsoft.com/en-us/library/ms132151(v=vs.110).aspx
Hope this helps :)

Using string in place of property name (LINQ)

I have been able to get the values from tables using linq.
var q=(from app in context.Applicant
where app.ApplicantName=="")
Now what I want is this:
var q=(from app in context.Applicant
where app.stringIhave =="") // so instead of column name I have string which has same name as column.
Is it possible to specify string in Select as this is not sure what I will get in each case, I need different data all the time.
Is it possible to do so?
If no, then I will figure out something else.
Update
I have a GlobalString, which holds the column name of a table.
So when I query that table, I only specify from string which column value I want to get:
var q=(from app in context.Applicants
where app.ID==1013
select GlobalString //which is specifying that I want to get value from which column, as column name is not fixed.
//where GlobalString can have values like: app.FirstName..app.LastName etc
Update1:
var q = context.Applicants.Select("new(it.ApplicantFirstName as FirstName, it.ApplicantLastName as LastName)");
Error Message:
The query syntax is not valid. Near keyword 'AS'
You can use Dynamic Linq (available from NuGet) for that:
var q = context.Applicant.Where(app.stringIhave + " = #0", "");
for select you can try something like this
var q = context.Applicant.Select("new(it.FirstName as FirstName, it.LastName as LastName)");
so you only need construct string for that format

Returning an Object[][] gives NullPointerException

I have an Access database which I need to retrieve all fields except the first and last and display it in a JTable. Everything works perfectly fine when I create my Object[][] but when i return it, i get a NullPointerException. I tried to find where there could be a null value in the database by printing the whole object out but that works fine and no values are null. Why would returning the Object[][] give me a NullPointerException and how can i fix it?
the stack trace is:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
public Object [] [] SetTrainingLogTable() throws SQLException
{
DatabaseConnection connection = new DatabaseConnection();
//Retrieves all the data from the TrainingLog table
ResultSet resultset = connection.SelectStatements("SELECT * FROM TrainingLog");
//Retrieves the number of entries
ResultSet numberofworkouts = connection.SelectStatements("SELECT COUNT(*) FROM TrainingLog");
int count = numberofworkouts.getInt(1);
number = count;
String[][] table = new String [count] [6];
//Number to incriment for while loops
int row = 0;
String date = "";
while(row<count)
{
date = resultset.getString(2);
table [row][0] = calculate.RefineDate(date);
table [row][1] = resultset.getString(3);
table [row][2] = resultset.getString(4);
table [row][3] = resultset.getString(5);
table [row][4] = resultset.getString(6);
table [row][5] = resultset.getString(7);
resultset.next();
row++;
}
Object[][] data = table;
connection.close();
return data;
}
I ran a debugger and it only gives the error when the return line is run.
It's best to post the stack trace and tell which line is raising the error. However, the typical way of writing such code is:
Connection con = ...;
Statement st = ...;
ResultSet rs = ...;
while (rs.next()) {
// ...
}
The result set starts out pointing before the first row. rs.next() returns whether there is a next row, and advances to it if it exists. Can you rewrite it in that style?
Other suggestions:
Can you create an actual object type instead of using Object[] to store the data from each row? Call it Workout.
Can you use a List<Workout> instead of your Object[][]?
Is the date stored in the database as a SQL DATE or TIMESTAMP? Then, don't convert it to a Java String: use java.sql.Date or java.util.Date. At work, I have a large old program that uses strings for dates, and it uses different formats to convert the values at different times. It's pretty miserable.
Don't use SELECT *. Give the names of the columns to return. Use the rs.getString("column_name") syntax.
There's no need to set one variable to the returned table and immediately set another variable to it.
Closing the connection or statement should be done in a finally block, or by try-with-resources.

Maximum value in datatable column c#

I have a set of text files that I am reading into a datatable. I want to be able to read the frist column (Id) and find out the highest number. Each of the files goes from 0 to at least 21 sequentially. I tried suggestions from the following link: How to select min and max values of a column in a datatable?
Sadly, I could not any to work. The one suggestion that kind of worked is shown in the second last line, but it returns a value of 8 or 9. Any suggestions as to how to properly get the results I am looking for?
string filePath = System.IO.Path.GetFullPath(curriculum);
DataTable curriculmDataTable = new DataTable();
curriculmDataTable.Columns.Add("Id");
curriculmDataTable.Columns.Add("Course");
curriculmDataTable.Columns.Add("Credit");
// Read in a file line-by-line, and store it
var txtFileLine = File.ReadAllLines(filePath).ToList();
//Reads line splits data to colums at tab (ASCII value 9)
txtFileLine.ForEach(line => curriculmDataTable.Rows.Add(line.Split((char)9)));
//Suggestions from link
int max = Convert.ToInt32(curriculmDataTable.Select("Id=max(Id)")[0][0]);
label1.Text = ""+ max;
The problem is that you have created string columns but you want to get the max-values according to their numeric value. The best way is to store the corrrect type in the first place. Then you could either use DataTable.Compute or Linq-To-DataSet:
create an int column:
curriculmDataTable.Columns.Add("Id", typeof(int));
convert the strings to int and add them to the table:
foreach(string line in File.ReadLines(filePath))
{
DataRow row = curriculmDataTable.Rows.Add();
string[] fields = line.Split(new[]{(char)9});
int id;
if(fields.Length == 3 && int.TryParse(fields[0], out id)
{
row.SetField("Id", id);
row.SetField("Course", fields[1]);
row.SetField("Credit", fields[2]);
}
}
Now you can use Linq:
int maxID = curriculmDataTable.AsEnumerable().Max(r => r.Field<int>("Id"));
DataTable.Compute (works also with earlier .NET versions):
int maxID = (int)curriculmDataTable.Compute("Max(Id)", "")
We can get max value from the column in a dataTable using this syntax
var maxValue = dataTblDetails.Compute("max(ColumnName)", string.Empty);

Adding a mock Datatable in Unit Testing

I am Unit Testing one of my functions. Here is my code:
public void TestLabels()
{
//Step 1: Creating a mock table with columns exactly like in the real table.
DataTable table = new DataTable();
DataRow mydatarow;
mydatarow = table.NewRow();
//Step 2: Adding the row as same as the Real Data!
mydatarow["Name"] = "Test";
mydatarow["Address"] = "00000 ST.";
mydatarow["ZipCode"] = "77665";
mydatarow["Tracking#"] = "";
table.Rows.Add(mydatarow);
foreach (DataColumn column in table.Columns)
Console.WriteLine(column.ColumnName);
//Step 3: Call method we are testing.
var updateTable = IceTechUPSClient.Instance.CreateLabels(table);
foreach (DataRow row in updateTable.Rows)
{
var trackingNumber = row["Tracking#"].ToString();
Assert.IsFalse(String.IsNullOrWhiteSpace(trackingNumber), "Expecting tracking number generated for every row!");
Assert.IsTrue(File.Exists(trackingNumber + ".gif"));
}
}
Now I am getting an error: Column 'Name' does not belong to table. As you can see I have specified column name "Name" here and also added that particular row. Then why I am getting this error? Any help?
Thanks!
You haven't set up your columns (unless you've missed out some code in your example).
You need to create the columns with the required names before you can access them like this:
var columnSpec = new DataColumn
{
DataType = typeof(string),
ColumnName = "Name"
};
this.table.Columns.Add(columnSpec);
When you read data from the database if you've set AutoGenerateColumns to true (the default) you don't need to do this explicitly as it's done for you behind the scenes.

Resources