perform "not in" query using linq from 2 datatables - asp.net

i have a datatable which contains "InvalidCodes".
Before uploading the data to database(data is still in datatable), i want to perform linq on the datatable to remove Invalid entries and move them in another datatable
datatable allEntries ( entries yet to be uploaded in database)
datatable InvalidCodes(single column datatable - retrieved from database)
datatable invalidEntries
right now "allEnties" contains valid entries and invalid entries. the linq query on "allEntries" should move the nonexistend code entries to invalidEntries datatable.
plz help me perform this.
below is the query i formed but its not valid
string query = "select [CityCode] from [StateCity] ";
DataTable citylist = getDataTableFromSelect(query);
var result = from myrow in inputDt.AsEnumerable()
where !myrow.Field<string>("CityCode").Contains(from myrow2 in citylist.AsEnumerable() select myrow2.Field<string>("CityCode") )
select myrow;

I'd make a HashSet for the invalid city codes - this will allow the code to quickly/efficiently identify which of the codes are in the invalid set.
e.g. something like:
var invalidCityCodes = from myrow2 in citylist.AsEnumerable()
select myrow2.Field<string>("CityCode");
var invalidCityCodeHashSet = new HashSet<string>(invalideCityCodes);
var result = from myrow in inputDt.AsEnumerable()
where !invalidCityCodeHashSet.Contains(myrow.Field<string>("CityCode"))
select myrow;

You can also take both the results in 2 Different Lists and then you can
use
List1 = List1.RemoveAll(Item=>List2.Contains(Item))
This works fine with me and will work for you also.

Related

Using a Repeater with a dynamically generated table, ie, so unknown field names

I'm trying to produce a repeater showing amounts of money taken by various payment types into a table.
Payment types available come from a global settings file as an array, I am creating a dataTable by looping this list and extracting sales reports (there might be a more efficient way than this loop, but this is not my concern at the minute).
My question: How do I bind this to a repeater and display it when I dont necessarily know the table column names?
I've tried various methods to give the table a header row and give the columns numerical names from a for > next loop, but am either getting no results, or
System.Data.DataRowView' does not contain a property with the name '7'. < or whatever number
This is where I currently am:
EDIT: JUST REALISED MY CODE WAS AWFUL, SO UPDATED:
Dim paymentTable As New DataTable("paymentTable")
For j = 0 To UBound(paymentTypes)
Dim Type = Trim(paymentTypes(j))
Dim headers As DataColumn = New DataColumn(j.ToString)
paymentTable.Columns.Add(headers)
Next
Dim titleRow As DataRow = paymentTable.NewRow()
For k = 0 To UBound(paymentTypes)
Dim Type = Trim(paymentTypes(k))
titleRow.Item(k) = Type
Next
paymentTable.Rows.Add(titleRow)
Dim newRow As DataRow = paymentTable.NewRow()
For i = 0 To UBound(paymentTypes)
Dim Type = Trim(paymentTypes(i))
Try
newRow.Item(i) = '' GO OFF AND GET STUFF FROM DB
Catch
newRow.Item(i) = "0 "
End Try
Next
paymentTable.Rows.Add(newRow)
THIS EDITED CODE WORKS BUT I ONLY GET ONE ITEM
What I was hoping for would look something like:
card | cash | paypal ... etc (headings row)
£250 | £54 | £78 ... etc (values row)
Obviously there're a million ways this can be done, but this makes sense for my application, which has to be expandable and contractable depending on payment types available and this whole table needs to be repeated for multiple locations (also variable depending on who's viewing, and the number of locations in the system)
No, dont give up but just dont name columns by absolute number with no string before try
Dim headers As DataColumn = New DataColumn("col"+ j.ToString)

Massive Query with inner join not returning any data

I'm using the Massive Query method to write a simple join query against an Oracle database. This is my code with the query simplified even further by taking out some columns:
dynamic logTable = new DynamicModel("mydatabase", "table1");
var sb = new StringBuilder();
sb.Append("select CONTACT_ID from table1 inner join table2 on table1.ID = table2.ID ");
sb.Append("where table1.ID=:0");
dynamic dbResult = logTable.Query(sb.ToString(), id);
The following code gives me an error: 'object' does not contain a definition for 'CONTACT_ID'
string id = dbResult.CONTACT_ID.ToString();
If I take the exact query and run it through sqldeveloper, I get back the expected results. If I try to Query through Massive without a join, I get back an object I can work with.
Any ideas?
My mistake! I was expecting my query to return only one record, but forgot that Query returns IEnumerable. Solution is to take First() or loop over the results.

Format XML data to display on a gridview

I am trying to format XML data to display on a grid.
Page1.aspx. This inserts XML data stored a xmldatatype:
WorkHistory workhis = js.Deserialize<WorkHistory>(json);
XmlDocument work = (XmlDocument)JsonConvert.DeserializeXmlNode(json, "root");
objBLL.insert_XMLWork(work, Convert.ToInt64(ui.id));
Page2.aspx retrieves it and display on a grid:
DataTable FBWorkDt = objBLL.get_FacebookWork(FacebookUserId);
GrdWork.DataSource = FBWorkDt;
GrdWorkPub.DataBind();
get_FacebookWork(select workinfo from Fprofiles where Userid = FacebookUserId)
returns a DataTable
It displays in this format exactly.
WorkInfo
<root><work><employer><id>208571635850052</id><name>Netizen Apps</name></employer></work><id>1076483621</id></root>
How do I make a normal display instead of XML format?
Thanks
Sun
It depends a good deal on the shape of the DataTable you're returning, but assuming you want the display to be something like this:
`ID Name
-------------------- ---------------------
208571635850052 Netizen Apps`
You could use LINQ:
DataTable FBWorkDt = objBLL.get_FacebookWork(FacebookUserId);
var query = from x in FBWorkDt.AsEnumerable()
select new {
id = x.ID,
name = x.Name
};
GrdWork.DataSource = query.ToList();
GrdWorkPub.DataBind();
I haven't tried the code out, so there may be minor syntatic changes, but essentially what it's doing is:
Use LINQ to get a collection of a new anonymous type that has one entry per row with the id and name from the table. You have to use AsEnumerable() [contained in System.Data.DataSetExtensions].
Convert the LINQ result set to a List via .ToList() and bind it to the GridView.
If you can post a little more information - what exactly you mean by display, and the expected shape of the returned DataTable (i.e., what the columns in each row are) we can give you a better answer.
UPDATE
If you're storing the XML document above in your datastore and that is being returned in the table, try this code:
DataTable FBWorkDt = objBLL.get_FacebookWork(FacebookUserId);
XDocument xDoc = XDocument.Load(FBWorkDt.Rows[0][0].ToString());
var query = from x in xDoc.Descendants("employer")
select new
{
id = (string)x.Element("id"),
name = (string)x.Element("name")
}
GrdWork.DataSource = query.ToList();
GrdWorkPub.DataBind();
Same basic principal as above, except this time your querying over an XDocument instead of a DataTable.

How to insert a constant value into a column using ASP.Net SqlBulkCopy

In the below code, I am trying insert the records from excel to Database table, but an additional column is not passed through the excel, which has to be populated with a constant value(foreach loop with a different value) assigned from the requested page.
string CONSTANTVALUE="Test";
bulkCopy.DestinationTableName = "TABLE NAME";
bulkCopy.ColumnMappings.Add("TABLECOLUMN1", "EXCELCOLUMN1");
bulkCopy.ColumnMappings.Add("TABLECOLUMN2", "EXCELCOLUMN2");
bulkCopy.ColumnMappings.Add("TABLECOLUMN3", CONSTANTVALUE);
bulkCopy.WriteToServer(dr);
But the code doesn't work. Any ideas?
You can do it, by changing your command text. As below
string CONSTANTVALUE="Test";
OleDbCommand command=new OleDbCommand("select *,"+CONSTANTVALUE+" as [ConstantCol] from [sheet$]",ObleDbCon);
using (DbDataReader dr = command.ExecuteReader())
{
bulkCopy.DestinationTableName = "TABLE NAME";
bulkCopy.ColumnMappings.Add("TABLECOLUMN1", "EXCELCOLUMN1");
bulkCopy.ColumnMappings.Add("TABLECOLUMN2", "EXCELCOLUMN2");
bulkCopy.ColumnMappings.Add("TABLECOLUMN3", "ConstantCol");
bulkCopy.WriteToServer(dr);
}
I assume your dr is a reader of some kind. How is it populated? It may be possible to select a default value into a column and map that. Something like this (sql syntax)
select
EXCELCOLUMN1,
EXCELCOLUMN2,
'ConstantValueFromPage' as EXCELCUSTOM
from
sheet1
Then have:
bulkCopy.ColumnMappings.Add("TABLECOLUMN3", "EXCELCUSTOM");
HTH
Did you try setting a default value for you column in database? I think it's the most easiest way, as after inserting any record, the default value would also get inserted into the specified column (it acts like triggers).

Having problems with sqlDataReader

I am using a sqlDataReader to get data and set it to session variables. The problem is it doesn't want to work with expressions. I can reference any other column in the table, but not the expressions. The SQL does work. The code is below. Thanks in advance, Anthony
Using myConnectionCheck As New SqlConnection(myConnectionString)
Dim myCommandCheck As New SqlCommand()
myCommandCheck.Connection = myConnectionCheck
myCommandCheck.CommandText = "SELECT Projects.Pro_Ver, Projects.Pro_Name, Projects.TL_Num, Projects.LP_Num, Projects.Dev_Num, Projects.Val_Num, Projects.Completed, Flow.Initiate_Date, Flow.Requirements, Flow.Req_Date, Flow.Dev_Review, Flow.Dev_Review_Date, Flow.Interface, Flow.Interface_Date, Flow.Approval, Flow.Approval_Date, Flow.Test_Plan, Flow.Test_Plan_Date, Flow.Dev_Start, Flow.Dev_Start_Date, Flow.Val_Start, Flow.Val_Start_Date, Flow.Val_Complete, Flow.Val_Complete_Date, Flow.Stage_Production, Flow.Stage_Production_Date, Flow.MKS, Flow.MKS_Date, Flow.DIET, Flow.DIET_Date, Flow.Closed, Flow.Closed_Date, Flow.Dev_End, Flow.Dev_End_Date, Users_1.Email AS Expr1, Users_2.Email AS Expr2, Users_3.Email AS Expr3, Users_4.Email AS Expr4, Users_4.FNAME, Users_3.FNAME AS Expr5, Users_2.FNAME AS Expr6, Users_1.FNAME AS Expr7 FROM Projects INNER JOIN Users AS Users_1 ON Projects.TL_Num = Users_1.PIN INNER JOIN Users AS Users_2 ON Projects.LP_Num = Users_2.PIN INNER JOIN Users AS Users_3 ON Projects.Dev_Num = Users_3.PIN INNER JOIN Users AS Users_4 ON Projects.Val_Num = Users_4.PIN INNER JOIN Flow ON Projects.id = Flow.Flow_Pro_Num WHERE id = "
myCommandCheck.CommandText += QSid
myConnectionCheck.Open()
myCommandCheck.ExecuteNonQuery()
Dim count As Int16 = myCommandCheck.ExecuteScalar
If count = 1 Then
Dim myDataReader As SqlDataReader
myDataReader = myCommandCheck.ExecuteReader()
While myDataReader.Read()
Session("TL_email") = myDataReader("Expr1").ToString()
Session("PE_email") = myDataReader("Expr2").ToString()
Session("DEV_email") = myDataReader("Expr3").ToString()
Session("VAL_email") = myDataReader("Expr4").ToString()
Session("Project_Name") = myDataReader("Pro_Name").ToString()
End While
myDataReader.Close()
End If
End Using
This may be because column names need to be unique for the SqlDataReader to be able to index them using a string name for the column.
A couple of things:
1) You are executing the query 3 times. You can lose the ExecuteNonQuery and ExecuteScalar calls, and replace the while loop with "if myDataReader.Read() / end if" to get the data values for the first resulting record. If no records are found, no session variables are set, just as in your current code.
2) It looks more like the problem lies in your session management (ie getting values from Session) rather than your sql query, which looks OK to me.
Check:
that you have sessionState enabled in your web.config file,
that you don't reset the Session values anywhere, and
that you ask for the same Session field name when you are trying to send the email. (e.g. are you setting Session("DEV_Email") but asking for Session("DEV Email") (space instead of underscore) ?
Sorry everyone. The code works just fine. The sqlDataReader WILL accept expressions as column names.
The reason I was getting an error saying the value of the from and to parameters cannot be null. There was no data in that column for any of the records in my table.

Resources