Column Does not belong to table ? C# - c#

I am trying to retrieve value directly from data table and inserting into a new database table.
I have to get values from more than one table. So I have used INNER JOIN Query to get value from multiple table. The values are getting on data table "dt". Now I want to insert those values into my new table. But while using the given below code showing one error. Help me to find a proper solution. Thank You.
Code:
MailTableAdapters.tbl_MailTableAdapter EM;
EM = new MailTableAdapters.tbl_MailTableAdapter();
DataTable dt = new DataTable();
dt = EM.GetEmpMail();
foreach (DataRow r in dt.Rows)
{
string SiteName = r["Site_Name"].ToString();
string SiteID = r["Site_ID"].ToString();
string AssingnedTeam = r["Assingned_Team"].ToString();
string AssignedList = r["Assigned_List"].ToString();
string EmpID = r["Emp_ID"].ToString();
string EmpName = r["Employee_Name"].ToString();
string EMail = r["Email"].ToString();
}
SQL:
SELECT Site_Name, Site_ID, Assigned_Team, Assign_List, Emp_ID, Employee_Name, Email FROM tbl_AutoAssignCadTeam INNER JOIN tbl_MailTable ON tbl_MailTable.Team = tbl_Employee.Team INNER JOIN tbl_Emp ON tbl_EmployeeToTeam.Emp_ID = tbl_Emp.Emp_ID

Well, you select Assign_List from the database, but use Assigned_List in your code. Assigned_List is not in the columns selected from the database.

Related

How to Get correct DataColumn Properties from DB

I am using ADO.NET. When I want to save data to table in SQL I need to retrieve columns information in this table. By information I mean Column max size (I want to get 10 from nvarchar(10) column) and NULL or NOT NULL.
I am using next code:
var selectFromCmd = SqlCommandFactory.CreateCommand("select top 0 * from [dbo]." + destTableName, SqlConnection, SqlTransaction);
var dataAdapter = new SqlDataAdapter(selectFromCmd);
var destinationTable = new DataTable();
dataAdapter.Fill(destinationTable);
Then I get DataColumn like so:
var column = destinationTable.Columns["MyColumn"]
But AllowDBNull is always true
and MaxLength is always -1 even if this column is string
So, how can I get the correct information about column properties in ADO.NET ?
I would rather use the sys cataloge views for this query. Something like this....
SELECT c.name ColumnName
,t.Name Datatype
,c.max_length MaxLength
,c.is_nullable
FROM sys.columns c
INNER JOIN sys.types t ON c.user_type_id = t.user_type_id
WHERE c.object_id = object_id('Customers') --<-- your table name

use select statement to get Data from a DataTable

I have DataTable containing three columns, Name, Date and DialedNumber. I want to get rows on the basis of DialedNumber column having phone number like 03001234567 ...
I am filing datatable with an method return type is datatable.
{
DataTable dt = filldata();
}
Problem is how to use select statement to get rows having number 03001234567 or some other telephone number ?
Try this Suppose you have a variable **string str** which is having that telephone number which you want to get from that data table then you can use this
{
DataTable dt = filldata();
DataRow[] resut = dt.Select("DialedNumber ='" + str + "'");
}
It will return you those rows having same telephone number in column DialedNumber.
If you want to filter from the start, not getting all table rows every time, you should adjust your SQL statement:
SELECT * FROM Table WHERE DialedNumber = #dialedNumber
and in C# use SqlCommand.Parameters.AddWithValue(...) to add the #dialedNumber parameter to the query.
Try to use Linq to DataTable like this
var results = from myRow in dt.AsEnumerable()
where myRow.Field<String>("DialedNumber") == "03001234567"
select myRow;
You can use Linq to DataSet:
string number = "03001234567";
var rows = dt.AsEnumerable()
.Where(r => r.Field<string>("DialedNumber").Contains(number));
You even can project rows into strongly typed objects:
var people = from r in dt.AsEnumerable()
where r.Field<string>("DialedNumber").Contains(number)
select new {
Name = r.Field<string>("Name"),
Date = r.Field<DateTime>("Date"),
DialedNumber = r.Field<string>("DialedNumber")
};
Note: if you want to check exact match of dialed number, then instead of Contains(number) (which is equivalent of LIKE) use == number.
Try like this
private void GetRowsByFilter()
{
DataTable table = DataSet1.Tables["Table1"];
// Presuming the DataTable has a column named Date.
string expression;
expression = "DialedNumber ='03001234567 '";
DataRow[] foundRows;
// Use the Select method to find all rows matching the filter.
foundRows = table.Select(expression);
// Print column 0 of each returned row.
for(int i = 0; i < foundRows.Length; i ++)
{
Console.WriteLine(foundRows[i][0]);
}
}
DataTable.Select Method

Populate a List with all the table names which is having specified columns through sql in c#

I have a database in sql server which is having few tables in it.
I need to populate a listbox which contains a list of tables names from the database which contains a specified column name
say 'special' .
i have tried something like..
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
List<string> tables = new List<string>();
DataTable dt = connection.GetSchema("Tables");
foreach (DataRow row in dt.Rows)
{
string tablename = (string)row[2];
tables.Add(tablename);
}
listbox1.ItemsSource = tables;
connection.Close();
}
but it is showing all the tables present in the database..
but i want only those table which have a specific columns in a list...
Kindly suggest me the way ... :)
You can use this linq query (now tested):
List<string> tNames= new List<string>(); // fill it with some table names
List<string> columnNames = new List<string>() { "special" };
// ...
IEnumerable<DataRow> tableRows = con.GetSchema("Tables").AsEnumerable()
.Where(r => tNames.Contains(r.Field<string>("TABLE_NAME"), StringComparer.OrdinalIgnoreCase));
foreach (DataRow tableRow in tableRows)
{
String database = tableRow.Field<String>("TABLE_CATALOG");
String schema = tableRow.Field<String>("TABLE_SCHEMA");
String tableName = tableRow.Field<String>("TABLE_NAME");
String tableType = tableRow.Field<String>("TABLE_TYPE");
IEnumerable<DataRow> columns = con.GetSchema("Columns", new[] { database, null, tableName }).AsEnumerable()
.Where(r => columnNames.Contains(r.Field<string>("COLUMN_NAME"), StringComparer.OrdinalIgnoreCase));
if (columns.Any())
{
tables.Add(tableName);
}
}
IMHO you should simply query the INFORMATION_SCHEMA.COLUMNS table instead of trying to filter the returned schema. First retrieving the hole schema to just throw most of the data away is totally ineffective.
SELECT c.TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS c
WHERE c.COLUMN_NAME = 'YourLovelyColumnName'
Assuming you are working on SQL Server:
IF COL_LENGTH('table_name','column_name') IS NOT NULL
BEGIN
/*Column exists */
END
See more:
How to check if column exists in SQL Server table

How to copy all the rows in a datatable to a datarow array?

I have two tables:
tbl_ClassFac:
ClassFacNo (Primary Key)
,FacultyID
,ClassID
tbl_EmpClassFac:
EmpID, (Primary Key)
DateImplement, (Primary Key)
ClassFacNo
I want to know all the Employees who are on a specific ClassFacNo. ie. All EmpID with a specific ClassFacNo... What I do is that I first search tbl_EmpClassFac with the EmpID supplied by the user. I store these datarows. Then use the ClassFacNo from these datarows to search through tbl_ClassFac.
The following is my code.
empRowsCF = ClassFacDS.Tables["EmpClassFac"].Select("EmpID='" + txt_SearchValueCF.Text + "'");
int maxempRowsCF = empRowsCF.Length;
if (maxempRowsCF > 0)
{
foundempDT = ClassFacDS.Tables["ClassFac"].Clone();
foreach (DataRow dRow in empRowsCF)
{
returnedRowsCF = ClassFacDS.Tables["ClassFac"].Select("ClassFacNo='" + dRow[2].ToString() + "'");
foundempDT.ImportRow(returnedRowsCF[0]);
}
}
dataGrid_CF.DataSource = null;
dataGrid_CF.DataSource = foundempDT.DefaultView;
***returnedRowsCF = foundempDT.Rows;*** // so NavigateRecordsCF can be used
NavigateRecordsCF("F"); // function to display data in textboxes (no importance here)
I know the code is not very good but that is all I can think of. If anyone has any suggestions please please tell me. If not tell me how do I copy all the Rows in a datatable to a datarow array ???
"How to copy all the rows in a datatable to a datarow array?"
If that helps, use the overload of Select without a parameter
DataRow[] rows = table.Select();
DataTable.Select()
Gets an array of all DataRow objects.
According to the rest of your question: it's actually not clear what's the question.
But i assume you want to filter the first table by a value of a field in the second(related) table. You can use this concise Linq-To-DataSet query:
var rows = from cfrow in tbl_ClassFac.AsEnumerable()
join ecfRow in tbl_EmpClassFac.AsEnumerable()
on cfrow.Field<int>("ClassFacNo") equals ecfRow.Field<int>("ClassFacNo")
where ecfRow.Field<int>("EmpId") == EmpId
select cfrow;
// if you want a new DataTable from the filtered tbl_ClassFac-DataRows:
var tblResult = rows.CopyToDataTable();
Note that you can get an exception at CopyToDataTable if the sequence of datarows is empty, so the filter didn't return any rows. You can avoid it in this way:
var tblResult = rows.Any() ? rows.CopyToDataTable() : tbl_ClassFac.Clone(); // empty table with same columns as source table

how to get distinct records in datatable?

I am using C# + VS2008 + .Net + ASP.Net + IIS 7.0 + ADO.Net + SQL Server 2008. I have a ADO.Net datatable object, and I want to filter out duplicate/similar records (in my specific rule to judge whether records are duplicate/similar -- if record/row has the same value for a string column, I will treat them as duplicate/similar records), and only keep one of such duplicate/similar records.
The output needs to be a datatable, may output the same datatable object if filter operation could be operated on the same datatable object.
What is the most efficient solution?
Are you using .NET 3.5? If you cast your data rows, you can use LINQ to Objects:
var distinctRows = table.Rows.Cast<DataRow>().Distinct(new E());
...
public class E : IEqualityComparer<DataRow>
{
bool IEqualityComparer<DataRow>.Equals(DataRow x, DataRow y)
{
return x["colA"] == y["colA"];
}
int IEqualityComparer<DataRow>.GetHashCode(DataRow obj)
{
return obj["colA"].GetHashCode();
}
}
Or an even simpler way, since you're basing it on a single column's values:
var distinct = from r in table.Rows.Cast<DataRow>()
group r by (string)r["colA"] into g
select g.First();
If you need to make a new DataTable out of these distinct rows, you can do this:
var t2 = new DataTable();
t2.Columns.AddRange(table.Columns.Cast<DataColumn>().ToArray());
foreach(var r in distinct)
{
t2.Rows.Add(r);
}
Or if it would be more handy to work with business objects, you can do an easy conversion:
var persons = (from r in distinct
select new PersonInfo
{
EmpId = (string)r["colA"],
FirstName = (string)r["colB"],
LastName = (string)r["colC"],
}).ToList();
...
public class PersonInfo
{
public string EmpId {get;set;}
public string FirstName {get;set;}
public string LastName {get;set;}
}
Update
Everything you can do in LINQ to Objects can also be done without it: it just takes more code. For example:
var table = new DataTable();
var rowSet = new HashSet<DataRow>(new E());
var newTable = new DataTable();
foreach(DataColumn column in table.Columns)
{
newTable.Columns.Add(column);
}
foreach(DataRow row in table.Rows)
{
if(!rowSet.Contains(row))
{
rowSet.Add(row);
newTable.Rows.Add(row);
}
}
You could also use a similar strategy to simply remove duplicate rows from the original table instead of creating a new table.
You can do a select into with a group by clause, so not duplicates are created. Then drop the old table and rename the table into which you selected to the original table name.
I would do this in the database layer:
SELECT Distinct...
FROM MyTable
Or if you need aggregates:
SELECT SUM(Field1), ID FROM MyTable
GROUP BY ID
Put the SELECT statement in a stored procedure. Then in .net make a connection to the database, call the stored procedure, execute .ExecuteNonQuery(). Return the rows in a datatable and return the datatable back to your UI.

Categories