how to retrieve the value(string form) from dataTable and assign that value to int varaible.. would any one pls give idea about this
int value = 0;
int.tryParse(DataTable.Rows[0][0].ToString(), out value);
DataTable table = GetTable(); //Gets the DataTable
foreach (DataRow row in table.Rows)
{
foreach (var item in row.ItemArray) // Loops over all the items.
{
string val = item;
}
}
Related
I have an MVC application with a dynamic table on one of the pages, which the users defines how many columns the table has, the columns order and where to get the data from for each field.
I have written some very bad code in order to keep it dynamic and now I would like it to be more efficient.
My problem is that I don't know how to define the columns I should get back into my IEnumerable on runtime. My main issue is that I don't know how many columns I might have.
I have a reference to a class which gets the field's text. I also have a dictionary of each field's order with the exact property It should get the data from.
My code should look something like that:
var docsRes3 = from d in docs
select new[]
{
for (int i=0; i<numOfCols; i++)
{
gen.getFieldText(d, res.FieldSourceDic[i]);
}
};
where:
docs = List from which I would like to get only specific fields
res.FieldSourceDic = Dictionary in which the key is the order of the column and the value is the property
gen.getFieldText = The function which gets the entity and the property and returns the value
Obviously, it doesn't work.
I also tried
StringBuilder fieldsSB = new StringBuilder();
for (int i = 0; i < numOfCols; i++)
{
string field = "d." + res.FieldSourceDic[i] + ".ToString()";
if (!string.IsNullOrEmpty(fieldsSB.ToString()))
{
fieldsSB.Append(",");
}
fieldsSB.Append(field);
}
var docsRes2 = from d in docs
select new[] { fieldsSB.ToString() };
It also didn't work.
The only thing that worked for me so far was:
List<string[]> docsRes = new List<string[]>();
foreach (NewOriginDocumentManagment d in docs)
{
string[] row = new string[numOfCols];
for (int i = 0; i < numOfCols; i++)
{
row[i] = gen.getFieldText(d, res.FieldSourceDic[i]);
}
docsRes.Add(row);
}
Any idea how can I pass the linq the list of fields and it'll cut the needed data out of it efficiently?
Thanks, Hoe I was clear about what I need....
Try following:
var docsRes3 = from d in docs
select (
from k in res.FieldSourceDic.Keys.Take(numOfCols)
select gen.getFieldText(d, res.FieldSourceDic[k]));
I got my answer with some help from the following link:
http://www.codeproject.com/Questions/141367/Dynamic-Columns-from-List-using-LINQ
First I created a string array of all properties:
//Creats a string of all properties as defined in the XML
//Columns order must be started at 0. No skips are allowed
StringBuilder fieldsSB = new StringBuilder();
for (int i = 0; i < numOfCols; i++)
{
string field = res.FieldSourceDic[i];
if (!string.IsNullOrEmpty(fieldsSB.ToString()))
{
fieldsSB.Append(",");
}
fieldsSB.Append(field);
}
var cols = fieldsSB.ToString().Split(',');
//Gets the data for each row dynamically
var docsRes = docs.Select(d => GetProps(d, cols));
than I created the GetProps function, which is using my own function as described in the question:
private static dynamic GetProps(object d, IEnumerable<string> props)
{
if (d == null)
{
return null;
}
DynamicGridGenerator gen = new DynamicGridGenerator();
List<string> res = new List<string>();
foreach (var p in props)
{
res.Add(gen.getFieldText(d, p));
}
return res;
}
I am trying to use following code to create the PIVOT but its not working.
It's giving me compile time error. I don't know linq so unable to use it.
Please help :
DataTable Pivot(DataTable dt, DataColumn pivotColumn, DataColumn pivotValue) {
// find primary key columns
//(i.e. everything but pivot column and pivot value)
DataTable temp = dt.Copy();
temp.Columns.Remove( pivotColumn.ColumnName );
temp.Columns.Remove( pivotValue.ColumnName );
string[] pkColumnNames = temp.Columns.Cast(<DataColumn>)
.Select( c => c.ColumnName )
.ToArray();
// prep results table
DataTable result = temp.DefaultView.ToTable(true, pkColumnNames).Copy();
result.PrimaryKey = result.Columns.Cast(<DataColumn>).ToArray();
dt.AsEnumerable()
.Select(r =>; r[pivotColumn.ColumnName].ToString())
.Distinct().ToList()
.ForEach (c => result.Columns.Add(c, pivotColumn.DataType));
// load it
foreach( DataRow row in dt.Rows ) {
// find row to update
DataRow aggRow = result.Rows.Find(
pkColumnNames
.Select( c => row[c] )
.ToArray() );
// the aggregate used here is LATEST
// adjust the next line if you want (SUM, MAX, etc...)
aggRow[row[pivotColumn.ColumnName].ToString()] = row[pivotValue.ColumnName];
}
return result;
}
Code from : http://michaeljswart.com/2011/06/forget-about-pivot/
Moreover it tried to use following code, it works well except for it is not giving total sum for Value Column
public DataTable GetInversedDataTable(DataTable table, string columnX, string columnY, string columnZ, string nullValue, bool sumValues)
{
//Create a DataTable to Return
DataTable returnTable = new DataTable();
DataTable tempTable = table.Clone();
if (string.IsNullOrEmpty(columnX))
{
columnX = table.Columns[0].ColumnName;
}
tempTable.Columns.Remove(columnX);
//Add a Column at the beginning of the table
//returnTable.Columns.Add(columnY);
returnTable = tempTable.Clone();
//Read all DISTINCT values from columnX Column in the provided DataTale
List<string> columnXValues = new List<string>();
foreach (DataRow dr in table.Rows)
{
string columnXTemp = dr[columnX].ToString();
if (!columnXValues.Contains(columnXTemp))
{
//Read each row value, if it's different from others provided, add to the list of values and creates a new Column with its value.
columnXValues.Add(columnXTemp);
returnTable.Columns.Add(columnXTemp);
}
}
//Verify if Y and Z Axis columns re provided
if (!string.IsNullOrEmpty(columnY) && !string.IsNullOrEmpty(columnZ))
{
//Read DISTINCT Values for Y Axis Column
List<string> columnYValues = new List<string>();
foreach (DataRow dr in table.Rows)
{
if (!columnYValues.Contains(dr[columnY].ToString()))
{
columnYValues.Add(dr[columnY].ToString());
}
}
//Loop all Column Y Distinct Value
foreach (string columnYValue in columnYValues)
{
//Creates a new Row
DataRow drReturn = returnTable.NewRow();
drReturn[0] = columnYValue;
//foreach column Y value, The rows are selected distincted
DataRow[] rows = table.Select((columnY + "='") + columnYValue + "'");
//Read each row to fill the DataTable
foreach (DataRow dr in rows)
{
string rowColumnTitle = dr[columnX].ToString();
//Read each column to fill the DataTable
foreach (DataColumn dc in returnTable.Columns)
{
if (dc.ColumnName == rowColumnTitle)
{
//If Sum of Values is True it try to perform a Sum
//If sum is not possible due to value types, the value displayed is the last one read
if (sumValues)
{
try
{
drReturn[rowColumnTitle] = Convert.ToDecimal(drReturn[rowColumnTitle]) + Convert.ToDecimal(dr[columnZ]);
}
catch
{
drReturn[rowColumnTitle] = dr[columnZ];
}
}
else
{
drReturn[rowColumnTitle] = dr[columnZ];
}
}
}
}
returnTable.Rows.Add(drReturn);
}
}
else
{
throw new Exception("The columns to perform inversion are not provided");
}
//if a nullValue is provided, fill the datable with it
if (!string.IsNullOrEmpty(nullValue))
{
foreach (DataRow dr in returnTable.Rows)
{
foreach (DataColumn dc in returnTable.Columns)
{
if (string.IsNullOrEmpty(dr[dc.ColumnName].ToString()))
{
dr[dc.ColumnName] = nullValue;
}
}
}
}
return returnTable;
}
GetInversedDataTable(dtNormal, "Dated", "OrderStatus", "Qty", " ", true);
Please help :)
Here is the code with the compilation errors corrected:
DataTable Pivot(DataTable dt, DataColumn pivotColumn, DataColumn pivotValue) {
// find primary key columns
//(i.e. everything but pivot column and pivot value)
DataTable temp = dt.Copy();
temp.Columns.Remove( pivotColumn.ColumnName );
temp.Columns.Remove( pivotValue.ColumnName );
string[] pkColumnNames = temp.Columns.Cast<DataColumn>()
.Select( c => c.ColumnName )
.ToArray();
// prep results table
DataTable result = temp.DefaultView.ToTable(true, pkColumnNames).Copy();
result.PrimaryKey = result.Columns.Cast<DataColumn>().ToArray();
dt.AsEnumerable()
.Select(r => r[pivotColumn.ColumnName].ToString())
.Distinct().ToList()
.ForEach (c => result.Columns.Add(c, pivotColumn.DataType));
// load it
foreach( DataRow row in dt.Rows ) {
// find row to update
DataRow aggRow = result.Rows.Find(
pkColumnNames
.Select( c => row[c] )
.ToArray() );
// the aggregate used here is LATEST
// adjust the next line if you want (SUM, MAX, etc...)
aggRow[row[pivotColumn.ColumnName].ToString()] = row[pivotValue.ColumnName];
}
return result;
}
I changed Cast(<DataColumn>) to Cast<DataColumn>() in two locations and got rid of the semicolon in the middle of a lambda expression. The second part of your question is a little trickier. You may want to ask it as its own question.
Good one., but you might want to replace the below line
.ForEach (c => result.Columns.Add(c, pivotColumn.DataType));
with this (change pivotColumn to pivotValue)
.ForEach (c => result.Columns.Add(c, pivotValue.DataType));
Works perfectly for my requirement.
I'm using Linq to return data from an XML file to a DataTable and that works. But now I'm trying to modify the code to loop through the DataTable. I created a custom class to model the data and have a List in my model. When I loop through the DataTable to display records it displays System.Collections.Generic.List`1[System.String] instead of the actual data. I'm not sure what to search to find the answer.
Snippet:
foreach (DataRow row in tbl.Rows)
{
myList = row["myList"] + ", " + myList;
}
The myList column is the List. I hope this makes sense.
Edited:
public static DataTable LINQToDataTable<T>(IEnumerable<T> varlist)
{
DataTable dtReturn = new DataTable();
// column names
PropertyInfo[] oProps = null;
if (varlist == null) return dtReturn;
foreach (T rec in varlist)
{
// Use reflection to get property names, to create table, Only first time, others will follow
if (oProps == null)
{
oProps = ((Type)rec.GetType()).GetProperties();
foreach (PropertyInfo pi in oProps)
{
Type colType = pi.PropertyType;
if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>)))
{
colType = colType.GetGenericArguments()[0];
}
dtReturn.Columns.Add(new DataColumn(pi.Name, colType));
}
}
DataRow dr = dtReturn.NewRow();
foreach (PropertyInfo pi in oProps)
{
dr[pi.Name] = pi.GetValue(rec, null) == null ?DBNull.Value :pi.GetValue
(rec,null);
}
dtReturn.Rows.Add(dr);
}
return dtReturn;
}
hobbiesList = (List<string>)row["hobbies"];
foreach (var item in hobbiesList)
{
hobbies.Add(item.ToString());
}
hobby = string.Join(", ", hobbies.ToArray());
hobbies.Clear();
I had to do the above to get it to work. I then add hobby to my output array.
I have a dataset table, I want to group it by column MOID, and then within this group I want to select the row which has max value of column radi.
Can anybody show me how to do it via LINQ to dataset?
Although the solution posted by Barry should work (with a few fixes), it is sub-optimal : you don't need to sort a collection to find the item with the maximum value of a field. I wrote a WithMax extension method, which returns the item with the maximum value of the specified function :
public static T WithMax<T, TValue>(this IEnumerable<T> source, Func<T, TValue> selector)
{
var max = default(TValue);
var withMax = default(T);
bool first = true;
var comparer = Comparer<TValue>.Default;
foreach (var item in source)
{
var value = selector(item);
int compare = comparer.Compare(value, max);
if (compare > 0 || first)
{
max = value;
withMax = item;
}
first = false;
}
return withMax;
}
It iterates the collection only once, which is much faster than sorting it just to get the first item.
You can then use it as follows
var query =
from row in table.AsEnumerable()
group row by row.Field<int>("MOID") into g
select g.WithMax(r => r.Field<int>("radi"));
This is untested but I think something like this should work:
var qry = from m in [YourDataSource]
group p by m.MOID into grp
select grp.OrderByDescending(a => a.RADI).First();
this works with one query!
public static T WithMax<T, TValue>(this IEnumerable<T> source, Func<T, TValue> keySelector)
{
return source.OrderByDescending(keySelector).FirstOrDefault();
}
I'm iterating the tables of a context and then the properties of those tables to eager load all columns in a context. I received some help via another question, but I don't seem to be able to figure out how to iterate the column properties of the actual table.
Final working code:
public static void DisableLazyLoading(this DataContext context)
{
DataLoadOptions options = new DataLoadOptions();
var contextTables = context.GetType().GetProperties().Where(n => n.PropertyType.Name == "Table`1");
foreach (var contextTable in contextTables)
{
var tableType = contextTable.GetValue(context, null).GetType().GetGenericArguments()[0];
var tableProperties = tableType.GetProperties().Where(n => n.PropertyType.Name != "EntitySet`1");
foreach (var tableProperty in tableProperties)
{
ParameterExpression paramExp = Expression.Parameter(tableType, "s");
Expression expr = Expression.Property(paramExp, tableProperty.Name);
options.LoadWith(Expression.Lambda(expr, paramExp));
}
}
context.LoadOptions = options;
}
You're only getting the ProperInfos. You need to get the values from the PropertyInfos:
var tablePropertInfos = context.GetType().GetProperties().Where(
n => n.PropertyType.Name == "Table`1");
foreach (var tablePropertyInfo in tablePropertInfos)
{
// Get the actual table
var table = tablePropertyInfo.GetValue(context, null);
// Do the same for the actual table properties
}
Once you have the PropertyInfo class, you need to get the value using the GetValue method.