Converting Data Table values into array of string values - c#

method1:
public void method1(DataTable ServerGroupIds)
{
obj.method2(ServerGroupIds);
}
method2 :
public static void method2(string[] servergroups)
{
obj.Message = userName + " has Un-Restricted the Project.";
}
Now I want to pass the DataTable values into the method2 String[] servergroups
How can I pass my DataTable values into an array of string values?
Sorry, Forget to mention I have 2 columns in my DataTable. !st column is ProjectId and Second Column is Server Group Id. Now I need only ServerGroup Id's in my array of string

Try this
public void method1(DataTable ServerGroupIds)
{
string [] serverGroups = ServerGroupIds.AsEnumerable().Select(t => t.Field<string>("ID")).ToArray<string>();
obj.method2(serverGroups );
}
Don't forget to include System.Linq
in t.Field<string>("ID"). Replace "ID" with the name of the column in the data table you want to put into the array

For a single row you can do this:
var rowAsString = string.Join(", ", ServerGroupIds.Rows[0].ItemArray);
Now add all the rows (by looping through your DataTable) rowAsString to a list:
List<string> list = new List<string>();
for (int i = 0; i < ServerGroupIds.Rows.Count; i++)
{
string rowAsString = string.Join(", ", ServerGroupIds.Rows[i].ItemArray);
list .Add(rowAsString );
}
string[] array = list.ToArray();
And pass to method2:
obj.method2(array);

Related

ClosedXML Sheet not being updated

I'm trying to update a sheet in C# using ClosedXML, but it seems the sheet is not being updated.
public string FeedAndFetchValueFromThirdSheet(List<string> listValueColl, IXLWorksheet worksheetThird)
{
int posTemp = worksheetThird.RowsUsed().Count(); // Value here is 1
string value = "";
foreach (var obj in listValueColl)
{
posTemp++;
worksheetThird.Cell(posTemp, 1).InsertData(obj);
}
int posUpdated = worksheetThird.RowsUsed().Count(); //After updating the sheet the value still remain 1
value = "A"+ (posTemp - listValueColl.Count()) +":A" + posTemp;
return value;
}
ClosedXML's InsertData() method uses any IList<T> as input, not a string or similar object.
So, just use List<string> or string[] array as container for data, that you want to insert.
The updated method:
public string FeedAndFetchValueFromThirdSheet(List<string> listValueColl, IXLWorksheet worksheetThird)
{
int posTemp = worksheetThird.RowsUsed().Count(); // Value here is 1
string value = "";
foreach (var obj in listValueColl)
{
posTemp++;
// Use IList (simple array, list, etc.) as container for data,
// that you want to insert.
string[] rowDataToInsert = { obj };
// Insert created array (not a string).
worksheetThird.Cell(posTemp, 1).InsertData(rowDataToInsert);
}
int posUpdated = worksheetThird.RowsUsed().Count(); //After updating the sheet the value still remain 1
value = "A" + (posTemp - listValueColl.Count()) + ":A" + posTemp;
return value;
}

How to get selected Data Columns from Datatable?

I have string array which contains some column names which may be valid or not.
I have to iterate over DataTable and return columns which are present in it.
Try this:
static public IEnumerable<DataColumn> GetColumns(DataTable dt)
{
var names = new[] { "foo", "bar" };
return dt.Columns.OfType<DataColumn>().Where(c => names.Contains(c.ColumnName));
}
public string getcolumns(DataTable dt,string[] array)
{
string columns = "";
foreach (DataColumn column in dt.Columns)
{
if(array.Contains(column.ColumnName))
{
columns += column.ColumnName + ",";
}
}
return columns;
}

Remove a certain value from string which keeps on changing

I'm trying to make a utility to generate an insert script of SQL tables along with relational table.
I got all the values in C#.
Now I want to remove the one column name and its value from the script.most probably the identity column.
For example: the string I have (which keeps on changing with table name and varies)
INSERT INTO Core.Customers ([customerId], [customername], [customeradress],[ordernumber])
VALUES (123, N'Rahul', N'244 LIZ MORN', 2334)
NOW I know I have to remove CustomerId (sometimes need to be replaces with #somevariable).
Please give me an efficient way how to retrieve customerId value and deleting column name and value.
I was looking for a method to find column value by column Name.
What I am doing is below - I know it's inefficient and can cause problem but for now it is working smoothly.
public string GetColumnValueToForDesiredColumnName(string row, TableInfo tableinfo, string NameofColumnTOfindvalueFor)
{
Dictionary<string, string> ValueTypedictionary = new Dictionary<string, string>();
string value = null;
// this code is quite messy - I need some suggestion on this one
string[] plusseperatedinsert = row.Replace("INSERT " + "[" + tableinfo.Schema + "].[" + tableinfo.TableName + "]", string.Empty).Trim().Replace("VALUES", "+").Split('+');
string[] columnvalues = plusseperatedinsert[0].Replace("(", string.Empty).Replace(")", string.Empty).Replace("(", string.Empty).Replace("[", string.Empty).Replace("]", string.Empty).Trim().Split(',');
string[] valuesfield = plusseperatedinsert[1].Replace("(", string.Empty).Replace(")", string.Empty).Replace("(", string.Empty).Replace("[", string.Empty).Replace("]", string.Empty).Trim().Split(',');
for (int index = 0; index < columnvalues.Length; index++)
{
ValueTypedictionary.Add(columnvalues[index], valuesfield[index]);
}
ValueTypedictionary.TryGetValue(NameofColumnTOfindvalueFor, out value);
return value;
}
This returns 123 as value.
And then I am using
string.Replace("[customerId],", string.empty).Replace(123, string.empty);
Create a special clas InsertQuery which stores pairs of column names with column values and then if you always need to remove or change an Id of a table you will know that it is on the first index of a list/array/whatever you use to store these pairs.
Define a method for removing this column and you are good to go.
So here is the code. You will probably change it somehow, it is just a proof of concept.
public class InsertQuery
{
private class Column
{
public string Name { get; set; }
public string Value { get; set; }
}
private readonly List<Column> columns = new List<Column>();
private readonly string tableName;
public InsertQuery(string tableName)
{
this.tableName = tableName;
}
public void AddColumn(string name, string value)
{
columns.Add(new Column { Name = name, Value = value });
}
public string RemoveColumnByName(string columnName)
{
var column = columns.First(c => c.Name == columnName);
var value = column.Value;
columns.Remove(column);
return value;
}
public string RemoveIdColumn()
{
var column = columns.First();
var value = column.Value;
columns.RemoveAt(0);
return value;
}
public override string ToString()
{
var sb = new StringBuilder();
sb.Append("INSERT INTO ");
sb.Append(tableName);
sb.Append(" (");
// append first all column names and then their values
return sb.ToString();
}
}
Trust me. Building such a tool using just string operations is not quite a good idea. In time you will want to add more functionality and you will be stuck with code that can be hardly extended. Encapsulation is a way to go.

Creating SQL table using C#

I would like to create two SQL tables using C#, within a loop. Each table is different, and has its column names stored in an array. Each array of column names is actually obtained from the header of a csv file.
### fnames is an array of file paths (2 csv files)
foreach string f in fnames)
{
## snip
using (StreamReader rdr = new StreamReader(f))
{
string header = read.line(); ## This is the array of table columns
}
string tab = Path.GetFileNameWithoutExtension(f);
string query = #"create table "+ tab + ..."; #I am not sure how to write the column names and types dynamically
}
Imagine that:
The columns for table 1 are : Date (datetime), Value (int)
The columns for table 2 are : Date (datetime), ID (varchar(255)), Return (int)
Note that the two tables have different columns with different types.
Would you have any suggestion as to how to achieve this?
Thank you!
You should break the problem apart, first you need to get a list of objects that define your column headers, after you have that you can loop over that list and build the query.
class HeaderInfo
{
public HeaderInfo(string header)
{
throw new NotImplementedException("Parse out your header info here and populate the class")
}
public string Name {get; private set;}
public string TypeInfo {get; private set;}
}
private List<HeaderInfo> ParseHeader(string header)
{
var headerInfo = new List<HeaderInfo>();
string[] headerItems = //Split your header line in to indvidual items some how
foreach(headerItem in headerItems)
{
headerInfo.Add(new HeaderInfo(headerItem));
}
return headerInfo;
}
private string TableString(List<HeaderInfo> headerInfo)
{
StringBuilder sb = new StringBuilder();
foreach(var info in headerInfo)
{
sb.AppendFormat("{0} {1}, ", info.Name, info.TypeInfo);
}
sb.Remove(sb.Length -2, 2); //Remove the last ", "
return sb.ToString();
}
private void YourMethod(string[] fnames)
{
### fnames is an array of file paths (2 csv files)
foreach string f in fnames)
{
## snip
List<HeaderInfo> headerInfo;
using (StreamReader rdr = new StreamReader(f))
{
string headerLine = read.line(); ## This is the array of table columns
headerInfo = ParseHeader(headerLine);
}
string tab = Path.GetFileNameWithoutExtension(f);
string query = String.Format(#"create table [{0}] ({1})", tab, TableString(headerInfo));
}
}

Get property name, need to retrieve only certain columns

Answer Summary:
Solved this problem using Jon Skeet's answer below. Here is the finished code
public static CSVData CreateCSVData(List<RegDataDisplay> rList,
string[] selectors)
{
CSVData csv = new CSVData(); // Create the CSVData object
foreach(string selector in selectors)
{
// Get the PropertyInfo for the property whose name
// is the value of selector
var property = typeof(RegDataDisplay).GetProperty(selector);
// Use LINQ to get a list of the values for the specified property
// of each RegDataDisplay object in the supplied list.
var values = rList.Select(row => property.GetValue(row, null)
.ToString());
// Create a new list with the property name to use as a header
List<string> templs = new List<string>(){selector};
// Add the returned values after the header
templs.AddRange(values);
// Add this list as a column for the CSVData object.
csv.Columns.Add(templs);
}
return csv;
}
Question
I am building my SQL query dynamically from user input, and then exporting the results to a CSV file. I have a class called RegDataDisplay which has a property for each of the possible columns returned by my query. I can tell what columns are being selected but in my CSV creator I need to be able to only output those specific columns.
In the example below, all of the data I have retrieved is in rList, and the names of the properties I need are in selectors. So I want to iterate through the list and then add only the properties I need to my CSV data.
public static CSVData CreateCSVData(List<RegDataDisplay> rList, string[] selectors)
{
CSVData csv = new CSVData();
for(int i = 0; i < selectors.Length; i++)
{
csv.Columns.Add(new List<string>(){selectors[i]});
}
// So now I have the headers for the CSV columns,
// I need the specific properties only which is where I'm stuck
for(int i = 0; i < selectors.Length; i++)
{
for(int j = 0; j < rList.Count; j++)
{
// If it was javascript I would do something like this
csv.Columns[i].Add(rList[j][selectors[i]]);
}
}
}
Thanks
EDIT: On the right track now but I'm coming up against an error "Object does not match target type".
public static CSVData CreateCSVData()
{
// I've created a test method with test data
string[] selectors = new string[] { "Firstname", "Lastname" };
List<RegDataDisplay> rList = new List<RegDataDisplay>();
RegDataDisplay rd = new RegDataDisplay();
rd.Firstname = "first";
rd.Lastname = "last";
rList.Add(rd);
CSVData csv = new CSVData();
foreach(string selector in selectors)
{
var property = typeof(RegDataDisplay).GetProperty(selector);
var values = rList.Select(row => property.GetValue(rList, null).ToString())
.ToList(); // Error throws here
csv.Columns.Add(values);
}
return csv;
}
Assuming you're on .NET 3.5 or higher, it sounds like you may want something like:
public static CSVData CreateCSVData(List<RegDataDisplay> rList,
string[] selectors)
{
CSVData csv = new CSVData();
foreach (string selector in selectors)
{
var prop = typeof(RegDataDisplay).GetProperty(selector);
var values = rList.Select(row => (string) prop.GetValue(row, null))
.ToList();
csv.Columns.Add(values);
}
}

Categories

Resources