Is this possible?
Let's say I had a simple IQueryable join like below:
var x = from t1 in Repo.GetThing1()
join t2 in Repo.GetThing2() on t1.Key equals t2.Key
select t1).ToList();
But let's there is a field on t1 that I want to set with t2. However I don't want to re-map all the fields from t1, I just want the ability to map that particular field in t1 from t2...
Sure:
var query = from t1 in Repo.GetThing1()
join t2 in Repo.GetThing2() on t1.Key equals t2.Key
select new { Existing = t1, NewValue = t2.SomeField };
var list = query.ToList();
foreach (var pair in list)
{
pair.Existing.SomeField = pair.NewValue;
}
(Then you can do whatever you want, of course.)
Related
var collection = from t1 in dt1.AsEnumerable()
join t2 in dt2.AsEnumerable()
on t1["id"] equals t2["id"]
select new { Name = t1["name"], Group = t2["group"] };
I want to select all columns of both table like join in SQL Server inner join query.
In Addition
How can i convert whole result of both tables to data-table?
var collection = from t1 in dt1.AsEnumerable()
join t2 in dt2.AsEnumerable()
on t1["id"] equals t2["id"]
select new { T1 = t1, T2 = t2 };
then...
EDIT:
Something along those lines
//clone dt1, copies all the columns to newTable
DataTable newTable = dt1.Clone();
//copies all the columns from dt2 to newTable
foreach(var c in dt2.Columns)
newTable.Columns.Add(c);
//now newTable has all the columns from the original tables combined
//iterates over collection
foreach (var item in collection) {
//creates newRow from newTable
DataRow newRow = newTable.NewRow();
//iterate the columns, gets values from either original table if column name is there
foreach(var c in newTable.Columns)
newRow[c.ColumnName] = item.T1.ContainsColumn(c.ColumnName) ? item.T1[c.ColumnName] : item.T2[c.ColumnName];
newTable.Rows.Add(newRow);
}
This will work. But if dt1 and dt2 share multiple columns with the exact same name, you might have some loss of data.
While you can't expand them to columns, you can simply return the entities. Eg:
select new { CTLJCRJOB, CTLRFDSTM }
If you need it flattened, then you will have to write out the mapping yourself, but will still be very trivial.
Referenced from:
Select All columns for all tables in join + linq join
ou have to specify each manually if you want to project into a flattened type. Your other option is to just have your combined type contain both objects, and the objects will naturally bring along their properties.
select new
{
Object1 = object1,
Object2 = output
};
And you would work with it like myObj.Object1.Property1, myObj.Object2.Property4, etc.
One final option that still involves some manual work is to define an appropriate type and have a constructor or a builder method that does the work of segmenting out your object properties into a flattened type. You still perform the manual mapping, but you isolate it from your query logic.
select new CombinedType(object1, output);
//or
select builder.GetCombinedType(object1, output);
Referenced From
Select all columns after JOIN in LINQ
var collection = (from t1 in dt1.AsEnumerable()
join t2 in dt2.AsEnumerable()
on t1 ["id"] equals t2 ["id"]
select new { Name = t1 ["name"], Group = t2 ["group"] }).ToList() ;
Hope this will help
I have this Select:
SELECT (MyFields)
FROM table1 T1
INNER JOIN table2 t2 ON t2.ID_t2 = T1.ID_T1
INNER JOIN
table3 t3 on t3.ID_t3=T1.ID_T1 and Left(t3.Other_t3_field,5)=t2.Another_t2_field
WHERE (Conditions)
Then, I tried in C#:
var query = from T1 in table1
join t2 in table2 on T1.ID_T1 equals t2.ID_t2
join t3 in **table3** on T1.ID_T1 equals v.ID_t3
join t4 in **table3** on t2.Other_t2_field equals Microsoft.VisualBasic.Strings.Left(t2.Another_t3_field, 5)
where (Conditions)
select new
{
(My fields)
};
Both works, but my C# query have more results then SQL Select, I don't know what I am doing wrong?
Well I'd start by changing the join on table 3 in the C# - use an anonymous type to join on multiple fields:
join t3 in table3 on new { Id = t1.ID_T1, X = t2.AnotherT2Field.Substring(0, 5) }
equals new { Id = t3.ID_T3, X = t3.OtherT3Field.Substring(0, 5) }
(I'd hope you can use Substring instead of Left here... it's much more idiomatic C#.)
You can add multiple join conditions with an anonymous type:
var query = from T1 in table1
join t2 in table2 on T1.ID_T1 equals t2.ID_t2
join t3 in **table3** on new {
ID = T1.ID_T1,
substring = t2.Other_t2_field
} equals new
{
ID = v.ID_t3,
substring = Microsoft.VisualBasic.Strings.Left(t2.Another_t3_field, 5)
}
where (Conditions)
select new
{
(My fields)
};
As Jon Skeet mentioned: you can also use Substring instead of Left.
Need to retrieve result set of both tables but i am getting null value in it
var Items = from t1 in dbModal.Table1
join t2 in dbModal.Table2 on t1.id equals t2.Id
select new
{ t1, t2.column };
need to map above query like this
Select t1.*,t2.Column from T1
join T2 on T1.id=T2.Id
I have two Data Tables: T1 and T2
T1 and T2 both have a Column Registration, but T2 doesn't have all the same Rows as T1.
I have to combine the Two Tables such that if the Registration Number is same get columns from T2, if not show Blank, but I need ALL ROWS FROM T1, (IF MATCH OR NOT).
I tried this but I only get matching Rows:
var results = from table1 in T1
join table2 in T2
on (String)table1["Registration"] equals (String)table2["Registration"]
select new
{
Registration = (String)table1["Registration"],
DistanceInKM = (decimal)table1["DistanceInKM"],
TotalDistanceTravelledKM = (Double)table2["TotalDistanceTravelledKM"]
};
You're performing an inner join, which only shows rows that exist on both sides.
Try using a left outer join instead:
var results = (from table1 in T1.AsEnumerable()
join tmp in T2.AsEnumerable() on table1["Registration"] equals tmp["Registration"] into grp
from table2 in grp.DefaultIfEmpty()
select new
{
Registration = (String)table1["Registration"],
DistanceInKM = (decimal)table1["DistanceInKM"],
TotalDistanceTravelledKM = (table2 == null ? (double?)null : (Double)table2["TotalDistanceTravelledKM"])
};
After a lot of search, I cannot find a simple answer to this following SQL Statement :
SELECT t1.LoginName, t0.BNAME
FROM USR02 AS t0
LEFT OUTER JOIN LoginData AS t1
INNER JOIN Mandants AS t2 ON t1.Id_Mandants = t2.Id_Mandants
ON t0.BNAME = t1.LoginName AND t0.MANDT = t2.CodeMandant
Because of the double ON statement I don't know how to write it in LINQ.
I've tried to simplify it but multiple primary key make the job hard.
Start by translating the SQL query to one that is more natural. Like this:
SELECT t1.LoginName, t0.BNAME
FROM USR02 AS t0
LEFT OUTER JOIN LoginData AS t1
ON t0.BNAME = t1.LoginName
INNER JOIN Mandants AS t2
ON t1.Id_Mandants = t2.Id_Mandants
WHERE t0.MANDT = t2.CodeMandant
Now it should be easy to translate this to LINQ. When you have you have set up the relationships in your entity model correctly, you would be able to write the following LINQ query:
from data in db.LoginData
where data.User.MANDT == data.Mandant.CodeMandant
select new { data.LoginName, data.User.BNAME };
btw. Why are you outputting both LoginData.LoginName as USR02.BNAME since they are always equal?
You need to convert your query to regular, 1-level join:
select t1.LoginName, t0.BNAME
from USR02 as t0
left outer join LoginData as t1 on t0.BNAME = t1.LoginName
inner join Mandants as t2 on t0.MANDT = t2.CodeMandant and t1.Id_Mandants = t2.Id_Mandants
Then it will be much easier to rewrite it on LINQ to Entities:
from t0 in db.t0
join t1 in db.t1 on t0.BNAME equals t1.LoginName
join t2 in db.t2 on new { t0.MANDT, t1.Id_Mandants} equals new { t2.CodeMandant , t2.Id_Mandants }
select new { t1.LoginName, t0.BNAME };
I like writing joins in this way
from t0 in db.t0
from t1 in db.t1.Where(x => t0.BNAME == x.LoginName).DefaultIfEmpty()
from t2 in db.t2.Where(x => t0.MANDT == x.CodeMandant)
.Where(x => t1.Id_Mandants == x.Mandants)
select new { t1.LoginName, t0.BNAME };