I have two DataTables with different data,common columns in both are quantity and Itemcode. I want to join the two tables together where two fields, (DataTable1.itemcode=DataTable2.itemcode) AND (DataTable1.quantity=DataTable2.quantity) OR ((DataTable1.quantity+1)=DataTable2.quantity) OR ((DataTable1.quantity+2)=DataTable2.quantity) . How would I write this in LINQ?
if item code is same and quantity is equal,exceeds by 1 or 2 then I should get joined result.
I tried using anonymous objects but that is for AND condition and OR condition was not fulfilled,so only itemcode and any one of these conditions was achieved at a time?
Please suggest me the correct way to do it?
You have to use the following syntax to access fields of the dataset:
[DataTable Name].Field<string>(indexNo or ColumnName)
So you can write the following linq to put a join between two data tables:
from t1 in dataTable.AsEnumerable()
//join between two tables
join t2 in dataTable2.AsEnumerable() on t1.Field<string>(0) equals t2.Field<string>(0)
//where conditions
where t1.Field<string>(0) == [value]
//select clause
select t1.Field<string>(colmNo)
Also you can convert the two data tables to IEnumerable by creating extension method.
Related
I have two MySql tables which I need to select a column from one, and where the results are used to select from another table. I know how to do it as two different select statements. However, I believe I can do it as a single statement but have no idea how.
Table one has two columns the second column has values which are also found in table two. I need to select all rows in table two which has the same values as those found in table one and where another column value is 0.
Any ideas how to go about doing this?
Use Join On tables to get columns form both table using query as
SELECT column_list
FROM table_1
LEFT JOIN table_2 ON
table_1.column = table_2.column;
Try to use Join query
SELECT columns
FROM table1
INNER JOIN table2
ON table1.column = table2.column;
I'm trying to compare two tables. I'd like to find out which rows exist in table1, and don't exist in table2. oData and oDataiSeries are DataTables, and properly populated.
var testing = from table1 in oData.AsEnumerable()
join table2 in oDataiSeries.AsEnumerable() on table1.Field<string>("SLOT") equals table2.Field<string>("SLOT")
where table1.Field<string>("SLOT") != table2.Field<string>("SLOT")
select table1;
testing ends up being null after the code runs. But if I were to do the following.
var testingtable1 = from table1 in oData.AsEnumerable()
select table1;
var testingtable2 = from table2 in oDataiSeries.AsEnumerable()
select table2;
testingtable1 and testingtable2 will be populated.
Is it because I'm trying to compare strings?
in testingtable1 and testingtable2, the column "SLOT" is String
Part of the problem:
I'm using VS 2015, and while debugging (hover mouse over DataTable object that should contain results), the Table isn't showing the proper results. It's showing the value of oData, instead of the comparison between oData and oDataiSeries. I'm not sure if I'm just misunderstanding how VS2015 displays var tables, or if this is a bug. If I bind the results DataTable to a gridview object, it'll display different rows as compared to the debugger. I ended up using #D Stanley solution, with a bit of modification.
I'd like to find out which rows exist in table1, and don't exist in table2.
You don't need a join for that. Just look for records that don't have a match in the second table:
var orphans = oData.AsEnumerable()
.Where(d => !oDataiSeries.AsEnumerable()
.Any(s => s.Field<string>("SLOT").Trim() == d.Field<string>("SLOT").Trim()));
or if you want to extract the values first to possibly improve performance, try
var series = oDataiSeries.AsEmumerable()
.Select(s => s.Field<string>("SLOT"));
var orphans = oData.AsEmumerable()
.Where(d => !oDataiSeries.Contains(d.Field<string>("SLOT"));
Is it because I'm trying to compare strings?
No, it's because join is an inner join by default, so ALL records will have matching values between the two datasets.
I need to be able to use with NHibernate criteria, the SQL's IsNull() function in C#.NET. I don't need to use it with LINQ.
Meaning that Table1 has the following columns:
Name | Description
Table2 has the following columns:
OriginalDescription | TranslatedDescription
And Table1.Description = Table2.OriginalDescription.
How would I write the following SQL statement with NHibernate criteria:
SELECT Table1.Model, IsNull(Table2.TranslatedDescription, Table1.Description)
FROM Table1
LEFT JOIN Table2 ON Table2.OriginalDescription = Table1.Description
The SQL statement above will give me the Names, and TranslatedDescriptions if the TranslatedDescriptions exist, otherwise it will return the Descriptions, for the records.
There cannot be duplicates of OriginalDescription in the Table2.
The solution of the ISNULL could be expressed like this:
// here is the criteria of the "Entity1" and the join to the "Entity2"
var criteria = session.CreateCriteria("Entity1", "table1");
criteria.CreateAlias("Entity2", "table2");
// here we drive the SELECT clause
criteria.SetProjection(
Projections.ProjectionList()
.Add(Projections.Property("Model"))
.Add(Projections.SqlFunction("COALESCE", NHibernateUtil.String
, Projections.Property("table2.TranslatedDescription")
, Projections.Property("table1.Description")
))
);
// just a list of object arrays
var list = criteria.List<object[]>();
So, what we do here, is a call of the SqlFunction. In this case one of the out-of-the-box mapped in many Dialects coming with NHibernate (but we can even extend the dialect with custom ones, an example how to: Nhibernate count distinct (based on multiple columns))
Must note, that the JOIN Clause is coming from the mapping. So this Table2.OriginalDescription = Table1.Description must come from a mapped relation many-to-one
I have a table called deliveries with columns id,shiftid, occurrence,delfee). I have three other tables delcash,delcc,delsplit. Del cash has columns (id,cost,paid), delcc has columns (id,cccost,ccpaid,cashtip), delsplit has columns(id,cashcost,cashpaid,cccost,ccpaid). The id links the delivery entries to one of the three other tables based on the type of payment. I am trying to get a list where the tables are joined together in a way so i can iterate through a list and get a table in a view that shows each delivery in order of occurrence as well as the tip and delivery fee of each delivery. Any idea if it is possible to do this? Or should I just use SQL?
SELECT deliveries.occurrence, deliveries.delfee,delcash.cost,delcash.paid,delcc.cost,delcc.paid,delcc.cashtip,
delsplit.cashcost,delsplit.cashpaid,delsplit.cccost,delsplit.ccpaid
FROM deliveries
LEFT JOIN delcash
ON deliveries.id = delcash.id
LEFT JOIN delcc
ON deliveries.id = delcc.id
LEFT JOIN delsplit
ON deliveries.id = delsplit.id
You can make a new class and let the three cost tables inherit from this class then you can apply the Table per Concrete Type strategy for mapping the tables.
see:
http://weblogs.asp.net/manavi/archive/2010/12/24/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-1-table-per-hierarchy-tph.aspx
OR redesign your database and apply Table per type strategy.
Try something like this:
var joinedDel = from delivery in tblDeliveries
join delC in tblDelCash on delivery.id equals delC.id
join delCC in tblDelCreditCard on delivery.id equals delCC.id
join delSplit in tblDelSplit on delivery.id equals delSplit.id
select new {
//Then create a new instance of Anonymous object where you will set all values of its properties
//For example, you can set ShiftID = delivery.ShiftID
};
I will also suggest to normalize first your tables(see this link for your reference) . This will give you more understanding on how will you join those tables properly.
I have 2 tables
TableA:
TableAID int,
Col1 varchar(8)
TableB:
TableBID int
Col1 char(8),
Col2 varchar(40)
When I run a SQL query on the 2 tables it returns the following number of rows
SELECT * FROM tableA (7200 rows)
select * FROM tableB (28030 rows)
When joined on col1 and selects the data it returns the following number of rows
select DISTINCT a.Col1,b.Col2 FROM tableA a
join tableB b on a.Col1=b.Col1 (6578 rows)
The above 2 tables on different databases so I created 2 EF models and retried the data separately and tried to join them in the code using linq with the following function. Surprisingly it returns 2886 records instead of 6578 records. Am I doing something wrong?
The individual lists seems to return the correct data but when I join them SQL query and linq query differs in the number of records.
Any help on this greatly appreciated.
// This function is returning 2886 records
public List<tableC_POCO_Object> Get_TableC()
{
IEnumerable<tableC_POCO_Object> result = null;
List<TableA> tableA_POCO_Object = Get_TableA(); // Returns 7200 records
List<TableB> tableB_POCO_Object = Get_TableB(); // Returns 28030 records
result = from tbla in tableA_POCO_Object
join tblb in tableB_POCO_Object on tbla.Col1 equals tblb.Col1
select new tableC_POCO_Object
{
Col1 = tblb.Col1,
Col2 = tbla.Col2
};
return result.Distinct().ToList();
}
The problem lies in the fact that in your POCO world, you're trying to compare two strings using a straight comparison (meaning it's case-sensitive). That might work in the SQL world (unless of course you've enabled case-sensitivity), but doesn't quite work so well when you have "stringA" == "StringA". What you should do is normalize the join columns to be all upper or lower case:
join tblb in tableB_POCO_Object on tbla.Col1.ToUpper() equals tblb.Col1.ToUpper()
Join operator creates a lookup using the specified keys (starts with second collection) and joins the original table/collection back by checking the generated lookup, so if the hashes ever differ they will not join.
Point being, joining OBJECT collections on string data/properties is bad unless you normalize to the same cAsE. For LINQ to some DB provider, if the database is case-insensitive, then this won't matter, but it always matters in the CLR/L2O world.
Edit: Ahh, didn't realize it was CHAR(8) instead of VARCHAR(8), meaning it pads to 8 characters no matter what. In that case, tblb.Col1.Trim() will fix your issue. However, still keep this in mind when dealing with LINQ to Objects queries.
This might happen because you compare a VARCHAR and a CHAR column. In SQL, this depends on the settings of ANSI_PADDING on the sql server, while in C# the string values are read using the DataReader and compared using standard string functions.
Try tblb.Col1.Trim() in your LINQ statement.
As SPFiredrake correctly pointed out this can be caused by case sensitivity, but I also have to ask you why did you write your code in such a way, why not this way:
// This function is returning 2886 records
public List<tableC_POCO_Object> Get_TableC()
{
return from tbla in Get_TableA()
join tblb in Get_TableB() on tbla.Col1 equals tblb.Col1
select new tableC_POCO_Object
{
Col1 = tblb.Col1,
Col2 = tbla.Col2
}.Distinct().ToList();
}
where Get_TableA() and Get_TableB() return IEnumerable instead of List. You have to watch out for that, because when you convert to list the query will be executed instantly. You want to send a single query to the database server.