So lets say I have a linq query like so
var stuff = from t1 in TableOne
let t2 = t1.TableTwo
where t1.id = "someId"
select
new
{
column1 = t1.Col1,
column2 = t2.Col1
column3 = (from t3 in TableThree
where t3.id = "someId"
select new SomeObject
{
Field1 = t3.Col1,
Field2 = t3.Col2
}).ToList()
}
Now in some scenarios i want to load the data in column 3, as in when a parameter passed in to the method contains this is not null. And when the parameter is null i dont want to load it for effciencies sake. Any suggestions on how i can achieve the desired result?
In your subquery check if the parameter someParameter is not null.
column3 = (from t3 in TableThree
where
someParameter != null &&
t3.id == "someId"
select new SomeObject
{
Field1 = t3.Col1,
Field2 = t3.Col2
}).ToList()
Related
I have done an inner join, it shows only the matching record with following query :-
var data = from t1 in ctx.tblEmp
join t2 in ctx.tblHelp
on t1.Field equals t2.Fld
where t1.Id == Id &&
t2.Id == Id
select new Settings { Master = t1.Labelname, OrderNo = t2.OrderNo};
I want all the records from tblEmp & only matching records from tblHelp.
How to do this?
Use as
var data = from t1 in ctx.tblEmp
join t2 in ctx.tblHelp
on t1.Field equals t2.Fld into u
from t2 in u.DefaultIfEmpty()
where t1.Id == Id &&
t2.Id == Id
select new Settings { Master = t1.Labelname, OrderNo = t2.OrderNo};
Try this
var data = from t1 in ctx.tblEmp
join t2 in ctx.tblHelp
on t1.Field equals t2.Fld into u
from t2 in u.DefaultIfEmpty()
where t1.Id == Id
orderby columnname // Added Order By
select new Settings { Master = t1.Labelname, OrderNo = t2.OrderNo==null ?"":t2.OrderNo};
var query = from t1 in ctx.tblEmp
join t2 in ctx.tblHelp on t1 equals t2.Fld into tempGroup
from subpet in tempGroup.DefaultIfEmpty()
select new { t1.Labelname, OrderNo = (subpet == null ? String.Empty : subpet.OrderNo) };
I need to write following T-SQL in LINQ:
SELECT T1.ID, T2.Name
FROM T1
LEFT JOIN T2 ON (T1.ID = I2.ID1 OR T1.ID = T2.ID2)
An OR-join would look like this in LINQ:
T1.Join(T2, t1=>new{}, t2=>new{}, (t1,t2)=>new{ID=t1.Id, t2=t2}).Where(o=>o.Id == o.t2.Id1 || o.Id==o.t2.Id2);
But that query is an INNER JOIN, not a LEFT JOIN.
Some kind of LEFT JOIN would look like this:
T1.GroupJoin(T2, t1 => t1.Id, t2 => t2.Id1, (t1, t2) => new { Id = t1.Id, Name1 = t2.Select(t => t.Name) }).DefaultIfEmpty()
.GroupJoin(T2, o => o.Id, t2 => t2.Id2, (i, j) => new { Id = i.Id, Name1 = i.Name1, Name2 = j.Select(t => t.Name) }).DefaultIfEmpty();
This query produces correct results, but makes 2 joins instead of 1. Or is it really equivalent to original T-SQL?
Does anybody know how to rewrite this query better?
This answer from a similar question gives us an easy way to write LEFT JOINs:
https://stackoverflow.com/a/4739738/1869660
var query = from t1 in T1
from t2 in T2.Where(tt2 => (t1.ID == tt2.ID1) || (t1.ID = tt2.ID2))
.DefaultIfEmpty()
select new { t1.ID, t2.Name }
To solve this with single linq, try using cross join
var results = (from a in test1
from b in test2
where a.ID == b.ID1 || a.ID == b.ID2
select new {x = a.ID, y = b.Name});
var LeftJoin = from emp in ListOfEmployees
join dept in ListOfDepartment
on emp.DeptID equals dept.ID into JoinedEmpDept
from dept in JoinedEmpDept.DefaultIfEmpty()
select new
{
EmployeeName = emp.Name,
DepartmentName = dept != null ? dept.Name : null
};
This is my query:
var results = from table1 in dtSplitDates.AsEnumerable()
join table2 in dtSplitDates.AsEnumerable() on (int)table1["FID"] equals (int)table2["FID"] into lj
from r in lj.DefaultIfEmpty()
select dtSplitDates2.LoadDataRow(new object[]
{
r["FID"],
r["SLNO"],
r == null ? string.Empty : r["Dates"]
}, false);
Currently i am joining on Column FID - due to which i am getting 36 records (duplicates):
However in order to avoid duplicates i need to join also on SLNO column but i am unable to write that query - please help.
As per my understanding you want two join condition; Try this
var results = from table1 in dtSplitDates.AsEnumerable()
join table2 in dtSplitDates.AsEnumerable()
on new {id1 =(int)table1["FID"], SLno1= (int)table1["SLNO"]}
equals new {id2=(int)table2["FID"], SLno2=(int)table2["SLNO"]} into lj
from r in lj.DefaultIfEmpty()
select dtSplitDates2.LoadDataRow(new object[]
{
r["FID"],
r["SLNO"],
r == null ? string.Empty : r["Dates"]
}, false);
Try to implement with this example:
For Multiple Joins:
var result=(from com in db.Company.AsEnumerable()
join c in db.Country.AsEnumerable() on com.CountryID equals c.CountryID
join s in db.State.AsEnumerable() on com.StateID equals s.StateID
join ct in db.City.AsEnumerable() on com.CityID equals ct.CityID
orderby com.Name
select new CompanyModel()
{
CompanyID = com.CompanyID,
Name = com.Name,
AddressLine1 = com.AddressLine1,
CountryID = com.CountryID,
StateID = com.StateID,
CityID = com.CityID,
Country = c.CountryID,
State = s.StateID,
City = ct.CityID,
Pin = com.Pin,
Phone = com.Phone,
}).Distinct().ToList();
I have two DataTables t1 and t2. I'm trying to perform a LINQ left join, multiple equijoin, to get the DataRows in t1 that are not in t2.
In SQL, what I'm trying to accomplish is:
select t1.*
from t1
left join t2
on t1.a=t2.a and
t1.b=t2.b and
t1.c=t2.c
where
t2.a is null
So far I have the following:
public DataTable t1_without_t2(DataTable t1, DataTable t2)
{
var query = from t1_row in t1.AsEnumerable()
join t2_row in t2.AsEnumerable()
on
new { t_a = t1_row["a"], t_b = t1_row["b"], t_c = t1_row["c"]}
equals
new { t_a = t2_row["a"], t_b = t2_row["b"], t_c = t2_row["c"]}
into leftJoinT1withoutT2
from join_row in leftJoinT1withoutT2.DefaultIfEmpty()
where t2_row["a"] == null
select new
{
j_a = join_row["a"],
j_b = join_row["b"],
j_c = join_row["c"],
};
DataTable dt = t1.Clone();
foreach (var result in query)
{
dt.LoadDataRow(
new object[]
{
result.j_a,
result.j_b,
result.j_c
},
false);
}
return dt;
}
This is failing on the line j_a = join_row["a"] with this message:
Column 'a' does not belong to table.
I thought that the into leftJoinT1withoutT2 line was supposed to put the results of the join into a var with the column structure of table t1, from which the non-matching entries would be removed using where t2_row["a"] == null . Is that not what's happening here? I'm a little confused.
It should look like this:
var query = from t1_row in t1.AsEnumerable()
join t2_row in t2.AsEnumerable()
on
new { t_a = t1_row["a"], t_b = t1_row["b"], t_c = t1_row["c"] }
equals
new { t_a = t2_row["a"], t_b = t2_row["b"], t_c = t2_row["c"] }
into leftJoinT1withoutT2
from join_row in leftJoinT1withoutT2.DefaultIfEmpty()
.Where(r => r == null)
select new
{
j_a = t1_row["a"],
j_b = t1_row["b"],
j_c = t1_row["c"],
};
Have a look at How to: Perform Left Outer Joins (C# Programming Guide).
The join_row gets null (i.e. default TSource value, see Enumerable.DefaultIfEmpty) when there is no matching element in t2, while t1_row always contains the joined value. So as far as you need only those rows for which join_row is null, I used .Where(r => r == null).
I have a search that looks for two things. Items and Contacts. They each have their own table with their own unique attributes. I am able to successfully search each independent of eachother and return the results to two list views. But is it ugly and paging has become a issue so I have to convert these two tables into a like result that I can display as a search result. These results have no relationship directly with eachother.
The group t3 by new is throwing me off. Do I have to group them to have it become a like result? The results currently get displayed in a ListView using for example <%#Eval("ItemName") %>
ItemContext db = new ItemContext(); //DB connection (Item,Contact)
var q = (from t1 in db.Item
join t2 in db.Categories on t1.CategoryID equals t2.CategoryID
join t7 in db.Divisions on t1.DivisionID equals t7.DivisionID
from t3 in db.Contacts
join t4 in db.Categories on t3.CategoryID equals t4.CategoryID
join t5 in db.Divisions on t3.DivisionID equals t5.DivisionID
join t6 in db.ContactTitle on t3.ContactTitlesID equals t6.ContactTitlesID
where
(DDLInt == 1 || t3.DivisionID == DDLInt) &&
//Contains
(
t3.ContactName.Contains(keyword) ||
t3.ContactEmail.Contains(keyword) ||
t3.ContactOPhone.Contains(keyword) ||
t3.ContactID.Equals(searchID)
)
group t3 by new
{
t3.ContactID,
t3.ContactName,
t3.ContactOPhone,
t3.ContactCell,
t3.ContactEmail,
t3.DivisionID,
t3.CategoryID,
t4.CategoryName,
t5.DivisionName,
t6.ContactTitlesName
}
into i
select new
{
i.Key.ContactID,
i.Key.ContactName,
i.Key.ContactOPhone,
i.Key.ContactEmail,
i.Key.ContactCell,
i.Key.CategoryName,
i.Key.DivisionName,
i.Key.CategoryID,
i.Key.DivisionID,
i.Key.ContactTitlesName
});
return q.ToList<dynamic>();
}
Use Union():
var contacts = from c in db.Contacts
select new {
Id = c.ContactID,
Name = c.ContactName,
Phone = c.ContactOPhone,
...
CategoryName = c.Category.CategoryName,
DivisionName = c.Division.DivisionName,
ContactTitlesName = c.ContactTitle.ContactTitlesName
}
var items = from t1 in db.Item
select new {
Id = t1.ItemID,
Name = t1.ItemName,
Phone = t1.??, // string.Empty?
... // more properties corresponding
// with the ones above
CategoryName = t1.Category.CategoryName,
DivisionName = t1.Division.DivisionName,
ContactTitlesName = string.Empty
}
var all = contacts.Union(items);