Subquery in using LINQ to SQL - c#

I have two tables.
1) Employee which have Id, Name, DeptId columns.
2) Department which have Id and DeptName columns.
I want to find all department which have no any employee using Linq to sql.
IN sql I use below query:
Select * from Department Where Id not in
(Select DeptId from Employee where DeptId Is not Null )

You can do this using LINQ left join like this:-
var result = from d in departments
join e in employees
on d.Id equals e.DeptId into es
from x in es.DefaultIfEmpty()
where x == null
select new Department { Id = d.Id, Name = d.Name};
Check this Fiddle for example with some custom objects.
In SQL this is equivalent to:-
SELECT D.*
FROM Department D
LEFT JOIN Employee E
ON D.Id = E.DeptId
WHERE E.id IS NULL

I hope this will work for you.
var empWithDepartments = from emp in Employee where emp.DeptId != NULL select emp.DeptId;
var result = from dep in Department where !empWithDepartments.Contains(dep.Id) select dep;

Try this:
var query = from d in Departments
where !(from e in Employees select e.FkDepartmentId).Contains(d.DepartmentId)
select d;
According to this post this would work with LINQ-TO-SQL but not with LINQ-TO-EF.

Related

How to add less than or equal to condition in linq inner join

We have two objects, Dates and ActiveEvents. Want to perform inner join on these with less than or equal to condition in linq. Same as ref of below SQL where consider #Tables are C# objects
Select A. from #Activities A
Inner Join #Dates D ON A.ActivityDate <= D.ProcessDate
Tried with below but it's not giving correct results.
var filteredActivity = (from e in ActiveEvents
from p in dates
where e.ActivityDate <= p.Date
select new ActiveEvent
{
ActivityDate = p.Date,
EventId = e.EventId
}).ToList();
And
var filteredActivity = (from e in ActiveEvents
from p in dates.Where(r => e.ActivityDate <= r)
select new ActiveEvent
{
ActivityDate = p.Date,
EventId = e.EventId
}).ToList();
Can you please suggest any better way to do this?
You can try this way
var filteredActivity = (from e in ActiveEvents
join p in dates
where e.ActivityDate <= p.ProcessDate
select new ActiveEvent
{
ActivityDate = p.Date,
EventId = e.EventId
}).ToList();
P/s: Ideally, between 2 tables should contain the foreign key to join like this join p in dates on e.Key equals p.ForeignKey
Based on your example, the query is filtering on ProcessDate but your linq query is filtering on p.Date. Are those the same field? The first example you gave should be correct.

C# - Join Syntax with two tables [duplicate]

I'm writing a LINQ to SQL statement, and I'm after the standard syntax for a normal inner join with an ON clause in C#.
How do you represent the following in LINQ to SQL:
select DealerContact.*
from Dealer
inner join DealerContact on Dealer.DealerID = DealerContact.DealerID
It goes something like:
from t1 in db.Table1
join t2 in db.Table2 on t1.field equals t2.field
select new { t1.field2, t2.field3}
It would be nice to have sensible names and fields for your tables for a better example. :)
Update
I think for your query this might be more appropriate:
var dealercontacts = from contact in DealerContact
join dealer in Dealer on contact.DealerId equals dealer.ID
select contact;
Since you are looking for the contacts, not the dealers.
And because I prefer the expression chain syntax, here is how you do it with that:
var dealerContracts = DealerContact.Join(Dealer,
contact => contact.DealerId,
dealer => dealer.DealerId,
(contact, dealer) => contact);
To extend the expression chain syntax answer by Clever Human:
If you wanted to do things (like filter or select) on fields from both tables being joined together -- instead on just one of those two tables -- you could create a new object in the lambda expression of the final parameter to the Join method incorporating both of those tables, for example:
var dealerInfo = DealerContact.Join(Dealer,
dc => dc.DealerId,
d => d.DealerId,
(dc, d) => new { DealerContact = dc, Dealer = d })
.Where(dc_d => dc_d.Dealer.FirstName == "Glenn"
&& dc_d.DealerContact.City == "Chicago")
.Select(dc_d => new {
dc_d.Dealer.DealerID,
dc_d.Dealer.FirstName,
dc_d.Dealer.LastName,
dc_d.DealerContact.City,
dc_d.DealerContact.State });
The interesting part is the lambda expression in line 4 of that example:
(dc, d) => new { DealerContact = dc, Dealer = d }
...where we construct a new anonymous-type object which has as properties the DealerContact and Dealer records, along with all of their fields.
We can then use fields from those records as we filter and select the results, as demonstrated by the remainder of the example, which uses dc_d as a name for the anonymous object we built which has both the DealerContact and Dealer records as its properties.
var results = from c in db.Companies
join cn in db.Countries on c.CountryID equals cn.ID
join ct in db.Cities on c.CityID equals ct.ID
join sect in db.Sectors on c.SectorID equals sect.ID
where (c.CountryID == cn.ID) && (c.CityID == ct.ID) && (c.SectorID == company.SectorID) && (company.SectorID == sect.ID)
select new { country = cn.Name, city = ct.Name, c.ID, c.Name, c.Address1, c.Address2, c.Address3, c.CountryID, c.CityID, c.Region, c.PostCode, c.Telephone, c.Website, c.SectorID, Status = (ContactStatus)c.StatusID, sector = sect.Name };
return results.ToList();
You create a foreign key, and LINQ-to-SQL creates navigation properties for you. Each Dealer will then have a collection of DealerContacts which you can select, filter, and manipulate.
from contact in dealer.DealerContacts select contact
or
context.Dealers.Select(d => d.DealerContacts)
If you're not using navigation properties, you're missing out one of the main benefits on LINQ-to-SQL - the part that maps the object graph.
Use Linq Join operator:
var q = from d in Dealer
join dc in DealerConact on d.DealerID equals dc.DealerID
select dc;
basically LINQ join operator provides no benefit for SQL. I.e. the following query
var r = from dealer in db.Dealers
from contact in db.DealerContact
where dealer.DealerID == contact.DealerID
select dealerContact;
will result in INNER JOIN in SQL
join is useful for IEnumerable<> because it is more efficient:
from contact in db.DealerContact
clause would be re-executed for every dealer
But for IQueryable<> it is not the case. Also join is less flexible.
Actually, often it is better not to join, in linq that is. When there are navigation properties a very succinct way to write your linq statement is:
from dealer in db.Dealers
from contact in dealer.DealerContacts
select new { whatever you need from dealer or contact }
It translates to a where clause:
SELECT <columns>
FROM Dealer, DealerContact
WHERE Dealer.DealerID = DealerContact.DealerID
Inner join two tables in linq C#
var result = from q1 in table1
join q2 in table2
on q1.Customer_Id equals q2.Customer_Id
select new { q1.Name, q1.Mobile, q2.Purchase, q2.Dates }
Use LINQ joins to perform Inner Join.
var employeeInfo = from emp in db.Employees
join dept in db.Departments
on emp.Eid equals dept.Eid
select new
{
emp.Ename,
dept.Dname,
emp.Elocation
};
Try this :
var data =(from t1 in dataContext.Table1 join
t2 in dataContext.Table2 on
t1.field equals t2.field
orderby t1.Id select t1).ToList();
OperationDataContext odDataContext = new OperationDataContext();
var studentInfo = from student in odDataContext.STUDENTs
join course in odDataContext.COURSEs
on student.course_id equals course.course_id
select new { student.student_name, student.student_city, course.course_name, course.course_desc };
Where student and course tables have primary key and foreign key relationship
try instead this,
var dealer = from d in Dealer
join dc in DealerContact on d.DealerID equals dc.DealerID
select d;
var Data= (from dealer in Dealer join dealercontact in DealerContact on dealer.ID equals dealercontact.DealerID
select new{
dealer.Id,
dealercontact.ContactName
}).ToList();
var data=(from t in db.your tableName(t1)
join s in db.yourothertablename(t2) on t1.fieldname equals t2.feldname
(where condtion)).tolist();
var list = (from u in db.Users join c in db.Customers on u.CustomerId equals c.CustomerId where u.Username == username
select new {u.UserId, u.CustomerId, u.ClientId, u.RoleId, u.Username, u.Email, u.Password, u.Salt, u.Hint1, u.Hint2, u.Hint3, u.Locked, u.Active,c.ProfilePic}).First();
Write table names you want, and initialize the select to get the result of fields.
from d1 in DealerContrac join d2 in DealerContrac on d1.dealearid equals d2.dealerid select new {dealercontract.*}
One Best example
Table Names : TBL_Emp and TBL_Dep
var result = from emp in TBL_Emp join dep in TBL_Dep on emp.id=dep.id
select new
{
emp.Name;
emp.Address
dep.Department_Name
}
foreach(char item in result)
{ // to do}

SQL query into LINQ in asp.net mvc

Please anyone can help me to write this sql query into Linq. i have tried..
this is my sql query
select o.OrderID,o.Nature,o.Date,od.TotalPrice,os.OrderStatus,lo.FirstName,lo.EmailAddress,lo.PhoneNumber
from [dbo].[Order] o
inner join [dbo].[tbl_OrderDetails] od on od.OrderID = o.OrderID
inner join [dbo].[tbl_OrderHistory] oh on oh.OrderID = o.OrderID
inner join [dbo].[tbl_Login] lo on o.UserID = lo.UserID
inner join dbo.tbl_OrderStatus os on oh.OrderStatusID= os.OrderStatusID
group by o.OrderID,o.Nature,od.TotalPrice,o.Date,os.OrderStatus,lo.FirstName,lo.EmailAddress,lo.PhoneNumber
and this is my try
public override orderDetailModel orderDetails(int id)
{
var results = from o in obj.Orders
join od in obj.tbl_OrderDetails on o.OrderID equals od.OrderID
join oh in obj.tbl_OrderHistory on o.OrderID equals oh.OrderID
join l in obj.tbl_Login on o.UserID equals l.UserID
join os in obj.tbl_OrderStatus on oh.OrderStatusID equals os.OrderStatusID
where (od.OrderID == id)
group o by new { o.Nature, o.OrderID } into
select new orderDetailModel
{
OrderID = o.OrderID,
OrderStatus = os.OrderStatus,
Date = o.Date,
DeliveryNature = o.Nature,
EmailAddress = l.EmailAddress,
FirstName = l.FirstName,
PhoneNumber = l.PhoneNumber,
TotalPrice = od.TotalPrice
};
//group o by new {o.OrderID};
orderDetailModel data = (orderDetailModel)results.FirstOrDefault();
return data;
}
but this is wrong query its not working fine please help me
You need to correct the group by clause, like you have in the SQL query like this:-
group new { o, l } by new { o.OrderID,o.Nature,od.TotalPrice,o.Date,os.OrderStatus,
l.FirstName, l.EmailAddress,l.PhoneNumber } into g
select new orderDetailModel
{
OrderID = g.Key.OrderID,
OrderStatus = g.Key.OrderStatus,
Date = g.Key.Date,
..and so on
};
Since you need the grouping on two tables Order & tbl_Login you will have to first project them as anonymous type group new { o, l } then specify all the groupings and finally while projecting use Key to get the respective items.
I guess that actually, also the SQL query is not correct.
I would simply use a SELECT DISTINCT ... instead of Grouping all the columns.
Anyway, first thing to do:
Check if databases is designed correctly. As far as i can see, if you're joining the table with their Ids, i don't understand why you need to group all the data. If you have duplicates, maybe the error is in the Database design.
If you can't change your Database, or you are happy with it, then use the following LINQ approach:
var distinctKeys = allOrderDetails.Select(o => new { o.OrderID, o.Nature, o.TotalPrice, o.Date,o.OrderStatus,o.FirstName, o.EmailAddress,o.PhoneNumber }).Distinct();
var joined = from e in allOrderDetails
join d in distinctKeys
on new { o.OrderID, o.Nature,o.TotalPrice, o.Date,o.OrderStatus, o.FirstName, o.EmailAddress, o.PhoneNumber } equals d select e;
joined.ToList(); // gives you the distinct/grouped list

How to select CompanyName and number of its products?

I want to write a Linq query that will return, columns with CompanyName of Supplier and number of all products of this company. Can you help me?
So far I got this:
var company = from pro in db.Products
join sup in db.Suppliers
on pro.SupplierID equals sup.SupplierID
group pro by pro.SupplierID
into g
select new { Name = g.Key, COUNT = g.Count() };
But this returns SupplierID not CompanyName. Database is Northwnd.
Use group join (i.e. join...into) to join suppliers with products and get all products of supplier in group:
from s in db.Suppliers
join p in db.Products
on s.SupplierID equals p.SupplierID into g
select new {
s.CompanyName,
ProductsCount = g.Count()
}
The following compiles and runs with Linq-for-objects. I can't vouch for whether Linq-to-SQL will cope.
var company = from sup in db.Suppliers
select new
{
Name = sup.CompanyName,
COUNT = db.Products
.Where(pro => pro.SupplierID == sup.SupplierID)
.Count()
};

Returning cross join instead of inner join

I have two result sets from database into object and when I inner join them, it returns cross join. Following is my code:
var nw = new NorthwindEntities();
var employee1 = (from emp in nw.Employees
join ord in nw.Orders on emp.EmployeeID equals ord.EmployeeID
where emp.EmployeeID == 5
select new
{
empID = emp.EmployeeID,
empName = emp.FirstName,
ordDate = ord.OrderDate
}).ToList();
var employee2 = (from emp in nw.Employees
join ord in nw.Orders on emp.EmployeeID equals ord.EmployeeID
where emp.EmployeeID == 5
select new
{
empID = emp.EmployeeID,
empName = emp.FirstName,
shpAddress = ord.ShipAddress
}).ToList();
var employee = from e1 in employee1
join e2 in employee2 on new { e1.empID } equals new { e2.empID }
select new
{
empID = e1.empID,
empName = e1.empName,
ordDate = e1.ordDate,
orAdd = e2.shpAddress
};
gvAll.DataSource = employee.ToList();
Now when I join employee1 and employee2 into employee, I get a cross join of those data set. Any help would be highly appreciated.
My main target behind this is to have data returned from database stored in some place temporarily so I can work it with later with other data retrieved from database.
employee1 and employee2 uses same query for employee id (5) except employee1 has empID, empName and OrderDate where as employee2 has empID, empName and shipAddress. Now I want empID, empName, OrderDate and ShipAddress out of employee1 and employee2 in employee. empID is common in both but I am getting a cross join. Thank you.
In employee1 and employee2 you will aslo need the OrderId column to and then join them by both cos you need to get an equal unique key on both tables.
and from what you wrote I think that empID is not unique in either tables cos you can have more orders for same empID
So first you need a unique key on both employee1 and employee2 then you can join on that.
The result returned from function is logically correct, it is not a cross join. empID has some duplicate row in some table so, data is looking like a cross join.
Use distinct then it will return your desired output.

Categories