linq multible join does not work in some empty tables - c#

hi I'm using 4 tables..
Sometimes it does not have information in the this tables(education or address or certificate)
so the results are coming empty..
If have information how can I say?
example
**PersonTable**
PersonId PersonName
1453 george
**Certificate Table**
CertificateId PersonId CertificateName ( 0 records)
**Addres Table**
AddresId PersonId Adress
1 1453 ......
2 1453 .....
3 1453 ......
4 1453 ......
5 1453 ........
**EducationTable**
EducationId PersonId Education
1 1453 school name
**BankTable**
BankId PersonId Bank ( 0 records )
Person table = 1 records
Certificates = 0 records
Address = 5 records
Education = 1 records
Bank = 0 records
var query = (from p in DbEntities.t_Person
join q in DbEntities.t_Address on p.PersonId equals q.addressId
join n in DbEntities.t_Education on p.PersonId equals n.EduId
join j in DbEntities.t_Certificate on p.PersonId equals j.CertificateId
join f in DbEntities.t_BankAccount on p.PersonId equals f.BankId
where p.PersonId.Equals(id)
select new { p, q, n, j, f }).FirstOrDefault();
return query values null ,
I do not see why these values​​?
Person table = 1 records
Address = 5 records
Education = 1 records
I thought about it, but did not
var query = (from p in DbEntities.t_Person
where p.PersonId.equlas(id)
select p).singleOrDefault();
query = from p in dbEntities.Address
WHERE P.AddressId.equlas(query.PersonId)
select p;

It's because you're doing an INNER JOIN, which will only return records if all join conditions are met! It looks like you want to do a LEFT JOIN, which will return all rows from the left table, and from the right table it will return any record that is found, and null otherwise. Here is a good post explaining the different types of joins, with diagrams!
The Linq-to-Entities way to do a left join is DefaultIfEmpty(). See MSDN for a usage example.

Related

SQL get Distinct rows from joined tables

I'm trying to determine the following from the joining of two tables:
Sample TableA: Contains 1 column consisting of unique IDs
ID Name Department
1 John IT
2 Jason Sales
3 Dany IT
4 Mike HR
5 Alex HR
Sample TableB: Contains multiple columns, including ID from TableA. For example:
ID AccountNumber WebID
1 10725 ABC1
1 10726 ABC1
1 10727 ABC1
2 20100 ABC2
2 20101 ABC2
3 30100 ABC3
4 40100 NULL
I want to get the following results:
ID Name WebID
1 John ABC1
2 Jason ABC2
3 Dany ABC3
4 Mike NULL
5 Alex NULL
I tried the following query, which is returning the correct rows for these sample tables:
Select count(a.ID), a.ID, a.Name, b.WebID from TableA a
left join TableB b on a.ID = b.ID
group by a.ID, a.Name, b.WebID
But my Actual Database tables, this query does not return correct number of rows: (30992)
TableA contains 29066 rows and TableB contains 23033 rows
The query should return 29066 rows, as it is Left Join.
When I checked the IDs that are in TableA, but not in TableB, there were 6033 rows:
Select * from TableA where ID not in (Select ID from TableB)
Am I missing something in the query?
TABLE B has duplicates of the ID column... the code below should work (but might not be the results you expect since I just do a max on the webid column which is fine if it is always the same but I need a rule if not)
I just saw you had a count... I added that in.
SELECT A.ID, A.Name, B.WebID
FROM TABLEA A
LEFT JOIN (
SELECT ID, MAX(WebID) AS WebID, count(*) as CNT
FROM TABLEB
GROUP BY ID
) B ON A.ID = B.ID
I think your query is as simple as that:
select a.ID,a.Name,b.WebID
from TableA a
left join TableB b on a.ID = b.ID

c# Linq How to write Innter Join using if condition

Here I have Two Tables Like
Employee
Id IsAccepected(bool) AccepectedBy EmpId
1 0 0 E1-1
2 1 2 E1-2
3 1 1 C1-1
Login
Id name
1 John
2 Mick
3 smith
Here my Question if IsAccepected==True then I need to Fetch Accepted By Record from Login Table
var x=(from n i in _db.EMployee
WHERE n.Empid='E1-1'
select n).Tolist();
foreach(var item in x){
if(item.IsAccepected==True){
.......
}
But I don't Need all those is it Possible to Write this condition Within The Linq
i guess you need this sql query need to be in linq right?
select b1.*,isnull((select 1 from A as a1 where a1.AccepectedBy=b1.Id and a1.EmpId='E1-2'),0) as isaccepted from B as b1
Something like below should work:
var x = from e in _db.Employee join l in _db.Login on e.AcceptedBy equals l.ID where e.Accepted == true select l;
Use this code by left join method-
select Login.name,Employee.EmpId from Employee left join Login on Employee.AccepectedBy=Login.Id where Employee.[IsAccepected(bool)]=1

How to retrieve all columns from table1 and matching columns from table2(Left outer join) using Linq

I have to retrieve all the columns from table1 and matching columns from table2. I have a stored procedure as :
alter Procedure [dbo].[usp_Property]
#UserId bigint =null
As
Begin
select P.PID, P.PropertyName, P.SBUArea, P.ListedOn,
P.Availability, P.Price, F.UserID, F.PID as FavProjId
from dbo.Property P left outer join dbo.Favorite F
on (F.PID=P.PID And F.UserID=#UserId)
I want to get Linq query for the same. So far I tried with something like
//User Id comes from session..
//var userId
var result=(from p in Properties
join f in Favorites
on p.PID equals f.PID into r
from r1 in r.DefaultIfEmpty()
where r1.UserID==userId
select new
{
p.PID,
p.PropertyName,
p.SBUArea, p.ListedOn,
r1.UserId
});
Can anyone please correct me. I want to use left outer join or any other alternate thing here.
If I beautify your SP's code, I get this:
DECLARE #UserId int
SET #UserId = 12435
SELECT
P.PID
,P.PropertyName
,P.SBUArea
,P.ListedOn
,P.Availability
,P.Price
,F.UserID
,F.PID AS FavProjId
FROM Property AS P
LEFT JOIN Favorite AS F
ON (F.PID=P.PID AND F.UserID = #UserId)
Now I wonder if you need that UserId in the WHERE clause of the SQL, or really in the join.
But anyway, here the LINQ-equivalent of exactly that SQL:
System.Int64 __UserId = 12435;
var query = (
from P in Repo.Property
from F in Repo.Favorite
.Where(fav=> fav.PID == P.PID && fav.UserID == __UserId)
.DefaultIfEmpty() // <== makes join left join
select new
{
PID = P.PID
,PropertyName = P.PropertyName
,SBUArea = P.SBUArea
,ListenOn = P.ListedOn
,Availabiity = P.Availability
,Price = P.Price
,UserId = F.UserID
,FavProjId = F.PID
}
);
var data = (query).ToList();
Use anonymous objects in your selection
var result = from t in table1
join x in table2
on t.id equals x.id
select new { id = t.id, col1 = t.col1, col2 = x.col2 }
If you will put the where clause after join you may get null reference exception because DefaultIfEmpty returns default value for non matching rows. You can filter the records before joining itself like this:-
var result=(from p in Properties
join f in Favorites.Where(x => x.UserID == userId)
on p.PID equals f.PID into r
from r1 in r.DefaultIfEmpty()
select new
{
p.PID,
p.PropertyName,
p.SBUArea,
p.ListedOn,
r1.UserId
});
Please note you need to access properties of Favorites using r1.
Update:
As far as I have understood you need all records from Property table and only matching rows from Favorite table. But you have a filter on your Favorite table so the ultimate data source will differ. Let me make my point clear by this example:-
Suppose you have following data in Property table:-
PID PropertyName Availability Price
1 aaa true 20
2 bbb false 10
3 ccc true 50
4 ddd false 80
5 eee true 55
6 fff false 70
and Favorite table like this:-
FID PID UserId
1 4 1001
2 2 1005
3 5 1007
And let's say you want all records for UserId 1005, then the result should contain all the property Id's from 1 till 6 even if UserId 1005 doesn't match for property Id's 4 & 2 right? So the query above is as per this understanding. Check this Fiddle with same example and output.

left join with 3 tables mysql

I have 3 tables in my Database
and i want to retrieve all products with their quantity from bill_Details tables.
This is the query:
SELECT p.prod_Id,p.prod_Name,COALESCE(sum(b.de_Quantity+b.de_Bonus),0)
,p.prod_Cost,p.prod_ExpDate,p.prod_BonusInfo,p.prod_Note
FROM (products p
LEFT JOIN bill_Details b
ON p.prod_Id=b.prod_Id)
LEFT JOIN bills a
ON b.bill_Id = a.bill_Id and a.cus_Sup=1 and a.archived=0
GROUP BY p.prod_Id, p.prod_Name,p.prod_Cost,p.prod_ExpDate,p.prod_BonusInfo,
p.prod_Note
ORDER BY p.prod_Name asc
The issue is that this query retrieve the same quantity when a.cus_Sup=1 or a.cus_Sup=0 !
Knowing that when a.cus_Sup=0 quantity should be 0 , and when a.cus_Sup=1 it's 29.5 for a specific product.
This is the data:
Below Query works for your case.
SELECT p.prod_id,
p.prod_name,
COALESCE(Sum(b.de_quantity + b.de_bonus), 0),
p.prod_cost,
p.prod_expdate,
p.prod_bonusinfo,
p.prod_note
FROM products p
LEFT JOIN (SELECT bd.*
FROM bill_details bd
JOIN bills a
ON bd.bill_id = a.bill_id
WHERE a.cus_sup = 1
AND a.archived = 0) b
ON p.prod_id = b.prod_id
GROUP BY p.prod_id,
p.prod_name,
p.prod_cost,
p.prod_expdate,
p.prod_bonusinfo,
p.prod_note
ORDER BY p.prod_name ASC

Get the "latest" datetime from a large linq query that currently returns every record that has a datetime

I have a fairly long linq query and everything works as it should.. but in a final join i am doing an innerjoin on a table that has a log, the log returns more than 50 records, i just want the latest record..
Here is an example
var tst = from w in context.storage
join p in context.products on w.id equals p.wid
join l in context.logger on p.id equals l.pid
select new
{
storageid = w.id,
productid = p.id
productname = p.name
bought = l.when
};
So a quick explanation of what happens, each product is stored in a storage center and there is a log when that product was bought, if it was bought 100 times then there is 100 records in the logger.
So currently it returns 50 records for productid = 5 ... why .. because it was bought 50 times but i only want 1 record, hence i only want the latest date time for from the logger.
Can anyone help? I am a little stuck.
Use result.Distinct(x => x.Prop) to get unique entries only
Use result.Max(x => x.Prop) to get latest date, and Min() to get earliest.
This is a case where you want to restrict to collection of records on which to join, which you can do by coding the join manually (sort of):
from w in context.storage
join p in context.products on w.id equals p.wid
// "manual" join:
from l in context.logger.Where(l => l.pid == p.id).OrderByDescencing(l => l.when).Take(1)
select new
{
storageid = w.id,
productid = p.id
productname = p.name
bought = l.when
};
In fluent linq syntax this is a SelectMany with a result selector.

Categories