Getting Column Names of a Table Ado.NET - datatable

I'm trying to get column names of a table, but it only returns the column names such as TABLE_SCHEMA,TABLE_NAME,TABLE_CATALOG,TABLE_TYPE.
Here's the code;
DataTable table = con.GetSchema("Tables", new string[] { null, null, "Contact" });
var columnNames = (from DataRow r in table.Rows
from DataColumn c in table.Columns
select c.ColumnName).ToList();
I need to save the names in a list.Thanks.

try this:
DataTable table = con.GetSchema("Columns", new string[] { null, null, "Contact" });
you have to specify Columns instead of Tables as collectionName ...
you should also change your linq query to something like this:
var columnNames = (from r in tab.AsEnumerable()
select r.Field<string>("COLUMN_NAME")).ToList();

Related

Select a row in a DataTable and change the header name to a new name and order by first and last names

How do I reassign a header name using linq? I tried MyHeaderName but that doesn't work. Also I wanted to sort by first and last name.
DataTable dataTable = ...retrieve from some data set...
var myNames = dataTable.AsEnumerable().Select( x => x["first"] & x["last"], "MyHeaderName" ).orderBy("first", "last");
You can't just change the column name for a single DataRow. DataRows are tied to their parent DataTable (and therefore its columns and column names).
You can change the column name of the DataTable which will be reflected in all its DataRows...
dataTable.Columns["name"].ColumnName = "new name";
It looks like from your edit that you want to have a column containing the full name. You can do so by first creating a new column and then populate the DataRow fields in a loop...
dataTable.Columns.Add("fullName");
foreach (var row in dataTable.Rows)
{
row["fullName"] = row["first"].ToString() + " " + row["last"].ToString();
}
// gets an enumerable of DataRow (the entire row) sorted by first then last
var myNames = dataTable.AsEnumerable()
.OrderBy(r => r["first"].ToString())
.ThenBy(r => r["last"].ToString());
Or you can use LINQ to project to an anonymous object that has a field called FullName (you can add more fields that you need)...
var myNames = dataTable.AsEnumerable()
.OrderBy(r => r["first"].ToString())
.ThenBy(r => r["last"].ToString())
.Select(x => new { FullName = x["first"].ToString() + " " + x["last"].ToString() });
foreach (var person in myNames)
{
Console.WriteLine(person.FullName);
}

Select multiple column in Linq using List

I have a DropDownList and I fill it using linq. The code example below is working.
ddlPortal.DataSource = from rows in db.Portals select new
{rows.Id, rows.PortalName};
But I need to use it with List variable. What's the problem about the code below?
ddlPortal.DataSource = new List<string>(from rows in db.Portals select new {rows.Id.ToString(), rows.PortalName});
By the way I need to retrieve two columns for DataValueField and DataTextField of DropDownList .
That's not a List<string> but a list of an anonymous type. Use var:
var dataSource = db.Portals
.Select(rows => new {Id = rows.Id.ToString(),Portal = rows.PortalName} )
.ToList();
ddlPortal.DataSource = dataSource;

Add rows to a DataTable from a query expression result

I am trying to dynamically add rows to a datatable from a query expression result. However, I am getting the below exception :
"Cannot cast DBNull.Value to type 'System.Int16'. Please use a nullable type."
This is my code:
foreach (var linqItem in linqResult)
resultDT.Rows.Add(linqItem.GetType().GetProperties().Select(p => p.GetValue(linqItem, null)).ToArray());
Please help me figure out figure out this issue.
Additional Code:
var linqResult = from misDTRow in misUserDetailsDT.AsEnumerable()
join deptDTRow in departmentInfoDT.AsEnumerable()
on misDTRow.Field<Int16>("DepartmentID") equals deptDTRow.Field<Int32>("DeptID")
select
new
{
Username = misDTRow["LoginName"],
EmployeeID = misDTRow["EmployeeID"],
EmployeeName = misDTRow["EmployeeName"],
FoundIn = misDTRow["FoundIn"],
StatusInMIS = (bool)misDTRow["IsActive"] == true ? "Inactive" : "Active",
Department = deptDTRow["DeptName"]
};
DataTable Creation:
DataTable resultDT = new DataTable();
PropertyInfo[] propInfo = linqResult.First().GetType().GetProperties();
foreach (PropertyInfo property in propInfo)
resultDT.Columns.Add(property.Name, property.PropertyType);
I am creating the DataTable dynamically from the query result.
try change to int? instead of int
"Cannot cast DBNull.Value to type 'System.Int16'. Please use a nullable type."
this is because you trying to cast the nullable type to int.
Check your database table which column allow null. Then you can cast it to nullable type.
For example :
misDTRow.Field<Int?>("DepartmentID") equals deptDTRow.Field<Int?>("DeptID")

Filter Datatable with linq by considering deleted rows

I have a following datatable -
static DataTable GetTable()
{
//
// Here we create a DataTable with four columns.
//
DataTable table = new DataTable();
table.Columns.Add("Dosage", typeof(int));
table.Columns.Add("Drug", typeof(string));
table.Columns.Add("Patient", typeof(string));
table.Columns.Add("Date", typeof(DateTime));
//
// Here we add five DataRows.
//
table.Rows.Add(25, "Indocin", "David", DateTime.Now);
table.Rows.Add(50, "Enebrel", "Sam", DateTime.Now);
table.Rows.Add(10, "Hydralazine", "Christoff", DateTime.Now);
table.Rows.Add(21, "Combivent", "Janet", DateTime.Now);
table.Rows.Add(100, "Dilantin", "Melanie", DateTime.Now);
return table;
}
// taken from following link
http://www.dotnetperls.com/datatable
On PageLoad I do the following code -
DataTable dt = GetTable();
dt.AcceptChanges();
dt.Rows[0].Delete();
var t = dt.AsEnumerable().Where(dataRow => dataRow.Field<string> ("Drug").Equals("Enebrel"));
It throws an error, that unable to get the data from deleted rows.
Is there any way to filter tell linq that do not take into account deleted rows.
Thanks,
Daljit Singh
You could specify to exclude the deleted row in your linq with something like this
var t = dt.AsEnumerable().Where(dataRow => dataRow.RowState != DataRowState.Deleted &&...
That should do the trick

Error: "The xml data type cannot be selected as DISTINCT because it is not comparable."

In my code I have the following Linq Query:
IQueryable<Data> charts = (from report in ctx.Charts group report by new
{
Name = report.ChartTitle.ChartType.ChartCategory.CategoryName,
id = report.ChartTitle.ChartType.ChartCategory.ChartCategoryId,
Period = report.Period
} into d
select new Data
{
Name = d.Key.Name,
Id = d.Key.id,
Period = d.Key.Period,
Reports = from r in d group r by new
{ Title = r.ChartTitle.Name, id = r.ChartTitle.ChartTitleId } into rs
select new Report
{
Title = rs.Key.Title,
Id = rs.Key.id,
Charts = (from c in rs group c by new
{
ChartId = c.ChartId,
FiscalYear = c.FiscalYear,
ModifiedDate = c.ChartView.ModifiedDate,
Function = c.Function.DisplayName,
ChartData=c.ChartView.ViewData
} into cs
select new ChartInfo
{
ChartId = cs.Key.ChartId,
FiscalYear = cs.Key.FiscalYear,
ModifiedDate = cs.Key.ModifiedDate,
Function = cs.Key.Function,
ChartData=cs.Key.ChartData
})
}});
In the above code if I exclude the "ChartData" field (which is of XML datatype), the query executes fine. But when ever I include this field it throws the following error :"The xml data type cannot be selected as DISTINCT because it is not comparable."
Let me know what I am missing here?
You can't group by XML types. This is a SQL restriction, not a LINQ-to-SQL retriction. (See Group by on XML column field with LINQ and select an xml type column in select query with group by SQL Server 2008)
Do you need to group by the XML column? The alternative would be to group by your other columns and then select the first XML value as a result.
Charts = (from c in rs group c by new
{
ChartId = c.ChartId,
FiscalYear = c.FiscalYear,
ModifiedDate = c.ChartView.ModifiedDate,
Function = c.Function.DisplayName,
} into cs
select new ChartInfo
{
ChartId = cs.Key.ChartId,
FiscalYear = cs.Key.FiscalYear,
ModifiedDate = cs.Key.ModifiedDate,
Function = cs.Key.Function,
ChartData=cs.Value.FirstOrDefault().ChartData
})
When using LINQ-to-SQL the items being grouped are still accessible - you don't need to include every 'selected' property / column in the group by` clause like you would in SQL.
You did not tell us what is the actual datatype of the ChartData, but from the error you are describing it looks like the problem is that whatever this datatype is it does not implement the IComparable interface which is a required interface if you want instances of the datatype to be comparable

Resources