Nhibernate Linq is null on left join - c#

Is there an easy way to do the following Nhibernate Linq statement
var query = from r in myTable.Query<MyTable>()
where r.Child == null
select r
The linq query above produces something similar to
SELECT MyTable.Id FROM MyTable WHERE MyTable.ChildId is null
it doesn't reference the child table and check if the left join is null like the following
SELECT MyTable.Id FROM MyTable
LEFT JOIN ChildTable ON MyTable.ChildId = ChildTable.Id
WHERE ChildTable.Id is null

var query = from r in myTable.Query<MyTable>()
where r.Child.Id == null
select r

Related

Condition == null and != null returns the same row

I make some joins to access the field IsVacancyActive.
When I write condition s.IsVacancyActive == null, I'm getting several rows and there is one which shouldn't be there.
And still if I write s.IsVacancyActive != null, then I'm geting another collection of rows, including that one row, which I have in the previous condition. How can it be? How it can have both values null and not null?
P.S. I use into for the left join
var data = (from c in db.Table1
join cm in db.Table2 on c.CandidateId equals cm.CandidateId into var1 from cm in var1.DefaultIfEmpty()
join lp in db.Table3 on c.KotelPositionId equals lp.PositionId into var2 from lp in var2.DefaultIfEmpty()
join pg in db.Table4 on lp.PositionId equals pg.PositionId into var3 from pg in var3.DefaultIfEmpty()
join lpt in db.Table5 on pg.LinkPositionGradeId equals lpt.LinkPositionGradeId into var4 from lpt in var4.DefaultIfEmpty()
join s in db.Table6 on lpt.LinkPositionTeamId equals s.LinkPositionTeamId into var5 from s in var5.DefaultIfEmpty()
join cv in db.Table7 on s.StaffId equals cv.VacancyId into var6 from cv in var6.DefaultIfEmpty()
join cvac in db.Table8 on c.CandidateId equals cvac.CandidateId into var7 from cvac in var7.DefaultIfEmpty()
where s.IsVacancyActive == null// Error
select new
{
c
}).Distinct()
.ToList();
If the LINQ query in the question ultimately resolves to a SQL database transaction, then the where clause:
where s.IsVacancyActive == null// Error
...may be parsed by LINQ to a null comparison in SQL, i.e. as X = NULL or X != NULL, which are both false in SQL.
Try:
where s.IsVacancyActive.HasValue

Linq Sql Int null equal to null. Not returning rows

I have a linq query with a where clause as below
var ExistingGroupDataSource = (from ppatg in dbContext.XXXXXXXXX
join pd1 in dbContext.XXXXXXXXXXX on ppatg.ScheduleID equals pd1.ScheduleID
where pd1.GroupID == null
select
new
{
FinishPDI = pd1.ProductionDateID,
FinishingDate = pd1.WorkFlowDate,
ppatg.GroupName,
ppatg.PNTGroupID
});
In the database GroupID is an int that can be null. The linq query returns rows without the filtered where clause but none when I include the where clause. There are null values in the GroupId column in the database.
It is definitely this statement that produces no results. All the literature on the subject online says that this is equivalent to
pd1.GroupID is null // in sql
I am getting results that contradict this
Sql code is
select pd1.ProductionDateID as FinishPDI, pd1.WorkflowDate as FinishingDate,GroupName ,PNTGroupId
from XXXXXXXXXXXX
inner join XXXXXXXXXXXX pd1 on
XXXXXXXXXXXX.ScheduleId = pd1.ScheduleID
where pd1.GroupID is null
You can combine your where with the join, which should give you the expected results:
var ExistingGroupDataSource = (from ppatg in dbContext.XXXXXXXXX
join pd1 in dbContext.XXXXXXXXXXX.Where(p => !p.GroupId.HasValue) on ppatg.ScheduleID equals pd1.ScheduleID
select
new
{
FinishPDI = pd1.ProductionDateID,
FinishingDate = pd1.WorkFlowDate,
ppatg.GroupName,
ppatg.PNTGroupID
});

How to prevent Entity Framework from adding ISNULL checks when joining on a nullable property with LINQ

I have a Linq query that is joining on 2 nullable properties.
var result = (from A in context.TableA
join B in context.TableB
on A.ExecutionId equals B.ExecutionId
where B.InsertedBy == userName
Both rep.ExecutionId and sch.ExecutionId are nullable int in the database. What I really want Entity Framework to generate is
select
column1
from TableA A
inner join TableB B on A.ExecutionId = B.ExecutionId
where B.InsertedBy = #username
but what I get is
select
column1
from TableA A
inner join TableB B on A.ExecutionId = B.ExecutionId
OR ((A.[ExecutionId] IS NULL) AND (B.[ExecutionId] IS NULL))
where B.InsertedBy = #username
(Neither one of the ExecutionIds are primary keys). The second query gives me WAY more records than what I need, but more importantly, is not the query that I want. How can I write the LINQ so that it produces the first query or an equivalent?
If you do not want any records where ExecutionID is null, then use a filter
var result = (from A in context.TableA.Where( a => a.ExecutionID != null )
join B in context.TableB.Where( b => b.ExecutionId != null )
on A.ExecutionId equals B.ExecutionId
where B.InsertedBy == userName
...`enter code here`

Select top 1 result from subquery in linq to sql

Here is my sql query as follow
select enq_Id,enq_FromName,
enq_EmailId,
enq_Phone,
enq_Subject,
enq_Message,
enq_EnquiryBy,
enq_Mode,
enq_Date,
ProductId,
(select top 1 image_name
from tblProductImage as i
where i.product_id=p.product_Id) as imageName,
p.product_Name,
p.product_code
from tblEnquiry as e
inner join tblProduct as p ON e.ProductId=p.product_Id
where ProductId is not null
And I try to convert this sql statement into linq as follow
var result = from e in db.tblEnquiries
join d in db.tblProducts
on e.ProductId equals d.product_Id
where e.ProductId != null
orderby e.enq_Date descending
select new {
e.enq_Id,
e.enq_FromName,
e.enq_EmailId,
e.enq_Phone,
e.enq_Subject,
e.enq_Message,
e.enq_EnquiryBy,
e.enq_Mode,
e.enq_Date,
d.product_Id,
d.product_Name,
imageName = (from soh in db.tblProductImages
where soh.product_id == e.ProductId
select new { soh.image_name }).Take(1)
};
But problem its giving me imageName in a nested list but i want that imageName just as a string .
I also check by using quick watch and in following image you can see that imageName appearing in inner list .
Instead of Take(1) which returns sequence IEnumerable<string>, use FirstOrDefault() which returns single string value (or null if there is no results). Also don't create anonymous type for subquery result:
imageName = (from soh in db.tblProductImages
where soh.product_id == e.ProductId
select soh.image_name).FirstOrDefault()
BTW FirstOrDefault() generates TOP(1) SQL.

Linq To Sql Left outer join - filtering null results

I'd like to reproduce the following SQL into C# LinqToSql
SELECT TOP(10) Keywords.*
FROM Keywords
LEFT OUTER JOIN IgnoreWords
ON Keywords.WordID = IgnoreWords.ID
WHERE (DomainID = 16673)
AND (IgnoreWords.Name IS NULL)
ORDER BY [Score] DESC
The following C# Linq gives the right answer.
But I can't help think I'm missing something (a better way of doing it?)
var query = (from keyword in context.Keywords
join ignore in context.IgnoreWords
on keyword.WordID equals ignore.ID into ignored
from i in ignored.DefaultIfEmpty()
where i == null
where keyword.DomainID == ID
orderby keyword.Score descending
select keyword).Take(10);
the SQL produced looks something like this:
SELECT TOP (10)
[t0].[DomainID]
, [t0].[WordID]
, [t0].[Score]
, [t0].[Count]
FROM [dbo].[Keywords] AS [t0]
LEFT OUTER JOIN
( SELECT 1 AS [test]
, [t1].[ID]
FROM [dbo].[IgnoreWords] AS [t1]
) AS [t2]
ON [t0].[WordID] = [t2].[ID]
WHERE ([t0].[DomainID] = 16673)
AND ([t2].[test] IS NULL)
ORDER BY [t0].[Score] DESC
How can I get rid of this redundant inner selection?
It's only slightly more expensive but every bit helps!
I think you can do something like this to eliminate the left join and maybe get more efficiency:
var query = (from keyword in context.Keywords
where keyword.DomainID == ID
&& !(from i in context.IgnoreWords select i.ID).Contains(keyword.WordID)
orderby keyword.Score descending
select keyword)
.Take(10);

Categories

Resources