Linq to Sql Concat Issue - linq

So I have this function:
public static BaseList GetVersesByChapterVerseRanges(string translation, BaseList criteriaList)
{
BaseList returnValue = new BaseList();;
if(criteriaList.Count() > 0)
{
List<VerseMaster.BusinessLayer.Vers> queryList = new List<Vers>();
int bookId = criteriaList[0].Book.BookId;
int StartChapter = criteriaList[0].StartChapter;
int EndChapter = criteriaList[0].EndChapter;
int StartVerse = criteriaList[0].StartChapterStartVerse;
int EndVerse = criteriaList[0].EndChapterEndVerse;
var searchQuery = (from v in VerseMaster.BusinessLayer.Controller.Controller.VerseMasterEntities.Verses where v.Translation.ToLower().StartsWith(translation.ToLower()) && v.BookId == bookId && v.ChapterNumber >= StartChapter && v.ChapterNumber <= EndChapter && (v.ChapterNumber == StartChapter ? (v.VerseNumber >= StartVerse) : true) && (v.ChapterNumber == EndChapter ? (v.VerseNumber <= EndVerse) : true) orderby v.ChapterNumber, v.VerseNumber ascending select v);
for(int i = 1; i < criteriaList.Count(); i++)
{
bookId = criteriaList[i].Book.BookId;
StartChapter = criteriaList[i].StartChapter;
EndChapter = criteriaList[i].EndChapter;
StartVerse = criteriaList[i].StartChapterStartVerse;
EndVerse = criteriaList[i].EndChapterEndVerse;
VerseMaster.BusinessLayer.DataObjects.Helper.VerseSearchCriteria criteria = criteriaList[i];
searchQuery = (System.Linq.IOrderedQueryable<VerseMaster.BusinessLayer.Vers>)searchQuery.Concat(from v in VerseMaster.BusinessLayer.Controller.Controller.VerseMasterEntities.Verses where v.Translation.ToLower().StartsWith(translation.ToLower()) && v.BookId == bookId && v.ChapterNumber >= StartChapter && v.ChapterNumber <= EndChapter && (v.ChapterNumber == StartChapter ? (v.VerseNumber >= StartVerse) : true) && (v.ChapterNumber == EndChapter ? (v.VerseNumber <= EndVerse) : true) orderby v.ChapterNumber, v.VerseNumber ascending select v);
}
string traceString = ((System.Data.Objects.ObjectQuery)searchQuery).ToTraceString();
foreach (var entVerse in searchQuery)
{
VerseMaster.BusinessLayer.DataObjects.IVerse verse = new VerseMaster.BusinessLayer.DataObjects.Verse();
LoadVerseFromEntityVerse(ref verse, entVerse);
Console.Write(String.Format("Chapter={0} Verse={1} Text={2}\n", entVerse.ChapterNumber, entVerse.VerseNumber, entVerse.Verse));
//returnValue.Add((VerseMaster.BusinessLayer.DataObjects.Verse)verse);
}
}
return returnValue;
}
So for some reason I had to convert each of the parameters that go into the linq query into standard ints because of an error, not sure if its related. So the generated sql is:
SELECT
[UnionAll2].[C1] AS [C1],
[UnionAll2].[C2] AS [C2],
[UnionAll2].[C3] AS [C3],
[UnionAll2].[C4] AS [C4],
[UnionAll2].[C5] AS [C5],
[UnionAll2].[C6] AS [C6]
FROM (SELECT
[UnionAll1].[VerseId] AS [C1],
[UnionAll1].[ChapterNumber] AS [C2],
[UnionAll1].[VerseNumber] AS [C3],
[UnionAll1].[Verse] AS [C4],
[UnionAll1].[Translation] AS [C5],
[UnionAll1].[BookId] AS [C6]
FROM (SELECT
[Extent1].[VerseId] AS [VerseId],
[Extent1].[ChapterNumber] AS [ChapterNumber],
[Extent1].[VerseNumber] AS [VerseNumber],
[Extent1].[Verse] AS [Verse],
[Extent1].[Translation] AS [Translation],
[Extent1].[BookId] AS [BookId]
FROM [dbo].[Verses] AS [Extent1]
WHERE (( CAST(CHARINDEX(LOWER(#p__linq__0), LOWER([Extent1].[Translation])) AS int)) = 1) AND ([Extent1].[BookId] = #p__linq__1) AND ([Extent1].[ChapterNumber] >= #p__linq__2) AND ([Extent1].[ChapterNumber] <= #p__linq__3) AND ((CASE WHEN ([Extent1].[ChapterNumber] = #p__linq__4) THEN CASE WHEN ([Extent1].[VerseNumber] >= #p__linq__5) THEN cast(1 as bit) WHEN ( NOT ([Extent1].[VerseNumber] >= #p__linq__5)) THEN cast(0 as bit) END ELSE cast(1 as bit) END) = 1) AND ((CASE WHEN ([Extent1].[ChapterNumber] = #p__linq__6) THEN CASE WHEN ([Extent1].[VerseNumber] <= #p__linq__7) THEN cast(1 as bit) WHEN ( NOT ([Extent1].[VerseNumber] <= #p__linq__7)) THEN cast(0 as bit) END ELSE cast(1 as bit) END) = 1)
UNION ALL
SELECT
[Extent2].[VerseId] AS [VerseId],
[Extent2].[ChapterNumber] AS [ChapterNumber],
[Extent2].[VerseNumber] AS [VerseNumber],
[Extent2].[Verse] AS [Verse],
[Extent2].[Translation] AS [Translation],
[Extent2].[BookId] AS [BookId]
FROM [dbo].[Verses] AS [Extent2]
WHERE (( CAST(CHARINDEX(LOWER(#p__linq__8), LOWER([Extent2].[Translation])) AS int)) = 1) AND ([Extent2].[BookId] = #p__linq__9) AND ([Extent2].[ChapterNumber] >= #p__linq__10) AND ([Extent2].[ChapterNumber] <= #p__linq__11) AND ((CASE WHEN ([Extent2].[ChapterNumber] = #p__linq__12) THEN CASE WHEN ([Extent2].[VerseNumber] >= #p__linq__13) THEN cast(1 as bit) WHEN ( NOT ([Extent2].[VerseNumber] >= #p__linq__13)) THEN cast(0 as bit) END ELSE cast(1 as bit) END) = 1) AND ((CASE WHEN ([Extent2].[ChapterNumber] = #p__linq__14) THEN CASE WHEN ([Extent2].[VerseNumber] <= #p__linq__15) THEN cast(1 as bit) WHEN ( NOT ([Extent2].[VerseNumber] <= #p__linq__15)) THEN cast(0 as bit) END ELSE cast(1 as bit) END) = 1)) AS [UnionAll1]
UNION ALL
SELECT
[Extent3].[VerseId] AS [VerseId],
[Extent3].[ChapterNumber] AS [ChapterNumber],
[Extent3].[VerseNumber] AS [VerseNumber],
[Extent3].[Verse] AS [Verse],
[Extent3].[Translation] AS [Translation],
[Extent3].[BookId] AS [BookId]
FROM [dbo].[Verses] AS [Extent3]
WHERE (( CAST(CHARINDEX(LOWER(#p__linq__16), LOWER([Extent3].[Translation])) AS int)) = 1) AND ([Extent3].[BookId] = #p__linq__17) AND ([Extent3].[ChapterNumber] >= #p__linq__18) AND ([Extent3].[ChapterNumber] <= #p__linq__19) AND ((CASE WHEN ([Extent3].[ChapterNumber] = #p__linq__20) THEN CASE WHEN ([Extent3].[VerseNumber] >= #p__linq__21) THEN cast(1 as bit) WHEN ( NOT ([Extent3].[VerseNumber] >= #p__linq__21)) THEN cast(0 as bit) END ELSE cast(1 as bit) END) = 1) AND ((CASE WHEN ([Extent3].[ChapterNumber] = #p__linq__22) THEN CASE WHEN ([Extent3].[VerseNumber] <= #p__linq__23) THEN cast(1 as bit) WHEN ( NOT ([Extent3].[VerseNumber] <= #p__linq__23)) THEN cast(0 as bit) END ELSE cast(1 as bit) END) = 1)) AS [UnionAll2]
So the problem is that for some reason its treating each of the parameters I give it as if I sent 3 sets of the same parameter and concatenated so its returning the same set of verses 3 times. I'm not sure why its doing this as I am not an expert of linq or the entity framework, any suggestions?

This is a very tricky example of the modified closure issue. In the for loop you generate a query part that uses the variables bookId etc. At the time that your query is executed it uses the values that these variables have at that moment, which are the values after the last iteration of the loop. (The tricky part is that usually the loop variable is captured, but here it is about variables that were declared outside the loop scope).
It would be different if you declared the variables within the for loop, because each query part would capture its own instance of the variable (which is called a closure).
The good news: you can do this and at the same time clean up your code!
if(criteriaList.Count() > 0)
{
IQueryable<Verse> baseQuery = null;
for(int i = 0; i < criteriaList.Count(); i++) // starting i = 0 now !
{
int bookId = criteriaList[0].Book.BookId;
int StartChapter = criteriaList[0].StartChapter;
int EndChapter = criteriaList[0].EndChapter;
int StartVerse = criteriaList[0].StartChapterStartVerse;
int EndVerse = criteriaList[0].EndChapterEndVerse;
searchQuery = (IOrderedQueryable<Vers>)searchQuery.Concat(
from v in Controller.Controller.VerseMasterEntities.Verses
where v.Translation.ToLower().StartsWith(translation.ToLower())
&& v.BookId == bookId
&& v.ChapterNumber >= StartChapter
&& v.ChapterNumber <= EndChapter
&& (v.ChapterNumber == StartChapter ? (v.VerseNumber >= StartVerse) : true)
&& (v.ChapterNumber == EndChapter ? (v.VerseNumber <= EndVerse) : true)
select v);
if (i == 0)
baseQuery = searchQuery;
else
baseQuery = baseQuery.Concat(searchQuery);
}
...
(do the ordering later)

Related

How to optimize nested CASE statements in PL/SQL

I am quite new to PL/SQL.
I am using the following nested CASE statement in a SELECT query. This follows the WHERE clause.
However, the query takes about 6 minutes to complete because of this nesting. If at least one CASE block is removed the query only takes about 1 minute to complete.
Is there any way to optimize this query?
(case
when a = 'STAGE PAYMENT' then
'Y'
when b not IN ('To be Received', 'Received') then
'N'
when c != (d - NVL(e, 0) - NVL(f, 0) - NVL(g, 0)) then
'Y'
when NVL(h, 0) + NVL(i, 0) + NVL(j, 0) <> 0 then
case
when c != k then
'Y'
when (-l != NVL(e, 0) + NVL(f, 0) + NVL(g, 0) + NVL(m, 0)) then
'Y'
else 'N'
end
else 'N'
end = 'Y')
I have tried using IF-ELSE blocks, but it did not do any good.
What about aggregating the nested cases in the parent case with ANDs?
(case
when a = 'STAGE PAYMENT' then
'Y'
when b not IN ('To be Received', 'Received') then
'N'
when c != (d - NVL(e, 0) - NVL(f, 0) - NVL(g, 0)) then
'Y'
when NVL(h, 0) + NVL(i, 0) + NVL(j, 0) <> 0 and c != k then
'Y'
when NVL(h, 0) + NVL(i, 0) + NVL(j, 0) <> 0 and (-l != NVL(e, 0) + NVL(f, 0) + NVL(g, 0) + NVL(m, 0)) then
'Y'
-- this serves as else 'N' in your code
when NVL(h, 0) + NVL(i, 0) + NVL(j, 0) <> 0 then
'N'
else 'N'
end = 'Y')

Cannot find why Stack Overflow error appears

I am trying to make an octree for randomly distributed set of particles. I have been trying to find where Stack Overflow Error appears whole day, but it was in vain. Could you please help me? The problem should be somewhere in (c == [0]) && (a > 0) part, however, I have no idea where. Thank you in advance!
type particle
R::Vector{Float64} # coordinates of the particle
m::Float64 # mass of the particle
a_tree::Float64 # acceleration of particle calculated from tree
a_exact::Float64 # acceleration of particle calculated by exact summation
end
type node
parent::Int64 # node's parent number
children::Vector{Int64} # set of childrens' numbers
l::Float64 # size of the node
R::Vector{Float64} # radius of geometric center
m::Float64 # total mass of the node
ptcl::Int64 # pointer to the particle in it
end
function problem3_2(N::Int64)
particles = Vector{particle}(N) # Basically, our system
tree = Vector{node}(1) # Initial tree (root)
tree[1] = node(0,[0],1.0,[0.0,0.0,0.0],0.0,0)
for i in eachindex(particles)
particles[i] = particle([rand() - 1/2, rand() - 1/2, rand() - 1/2], 1.0, 0.0, 0.0)
tree = InsertParticle(i,1,tree,particles)
end
return tree
end
function InsertParticle(i::Int64,k::Int64,tree,particles)
c = tree[k].children
a = tree[k].ptcl
if (c == [0]) && (a == 0)
tree[k].ptcl = i
elseif (c == [0]) && (a > 0)
j_1 = length(tree) + DetermOctant(particles[tree[k].ptcl],tree[k])
j_2 = length(tree) + DetermOctant(particles[i],tree[k])
tree[k].children = [x for x in length(tree)+1:length(tree)+8]
for p = 1:8
push!(tree,node(k,[0],tree[k].l/2,[0.0,0.0,0.0],0.0,0))
if (p == 1) || (p == 4) || (p == 5) || (p == 8)
tree[k+p].R[1] = tree[k].R[1] + tree[k+p].l/2
else
tree[k+p].R[1] = tree[k].R[1] - tree[k+p].l/2
end
if (p == 1) || (p == 2) || (p == 5) || (p == 6)
tree[k+p].R[2] = tree[k].R[2] + tree[k+p].l/2
else
tree[k+p].R[2] = tree[k].R[2] - tree[k+p].l/2
end
if (p == 1) || (p == 2) || (p == 3) || (p == 4)
tree[k+p].R[3] = tree[k].R[3] + tree[k+p].l/2
else
tree[k+p].R[3] = tree[k].R[3] - tree[k+p].l/2
end
end
InsertParticle(tree[k].ptcl,j_1,tree,particles)
InsertParticle(i,j_2,tree,particles)
tree[k].ptcl = 0
elseif (c != [0])
j = DetermOctant(particles[i],tree[k])
InsertParticle(i,tree[k].children[j],tree,particles)
end
return tree
end
function DetermOctant(x::particle,y::node)
c1 = y.R[1]; c2 = y.R[2]; c3 = y.R[3]
x1 = sign(x.R[1] - c1); x2 = sign(x.R[2] - c2); x3 = sign(x.R[3] - c3)
if (x1 > 0) && (x2 > 0) && (x3 > 0)
n = 1
elseif (x1 < 0) && (x2 > 0) && (x3 > 0)
n = 2
elseif (x1 < 0) && (x2 < 0) && (x3 > 0)
n = 3
elseif (x1 > 0) && (x2 < 0) && (x3 > 0)
n = 4
elseif (x1 > 0) && (x2 > 0) && (x3 < 0)
n = 5
elseif (x1 < 0) && (x2 > 0) && (x3 < 0)
n = 6
elseif (x1 < 0) && (x2 < 0) && (x3 < 0)
n = 7
else
n = 8
end
return n
end
Basically, I do know that the error should be somewhere here:
function InsertParticle(i::Int64,k::Int64,tree,particles)
c = tree[k].children
a = tree[k].ptcl
if (c == [0]) && (a == 0)
tree[k].ptcl = i
elseif (c == [0]) && (a > 0)
j_1 = length(tree) + DetermOctant(particles[tree[k].ptcl],tree[k])
j_2 = length(tree) + DetermOctant(particles[i],tree[k])
tree[k].children = [x for x in length(tree)+1:length(tree)+8]
for p = 1:8
push!(tree,node(k,[0],tree[k].l/2,[0.0,0.0,0.0],0.0,0))
if (p == 1) || (p == 4) || (p == 5) || (p == 8)
tree[k+p].R[1] = tree[k].R[1] + tree[k+p].l/2
else
tree[k+p].R[1] = tree[k].R[1] - tree[k+p].l/2
end
if (p == 1) || (p == 2) || (p == 5) || (p == 6)
tree[k+p].R[2] = tree[k].R[2] + tree[k+p].l/2
else
tree[k+p].R[2] = tree[k].R[2] - tree[k+p].l/2
end
if (p == 1) || (p == 2) || (p == 3) || (p == 4)
tree[k+p].R[3] = tree[k].R[3] + tree[k+p].l/2
else
tree[k+p].R[3] = tree[k].R[3] - tree[k+p].l/2
end
end
InsertParticle(tree[k].ptcl,j_1,tree,particles)
InsertParticle(i,j_2,tree,particles)
tree[k].ptcl = 0
elseif (c != [0])
j = DetermOctant(particles[i],tree[k])
InsertParticle(i,tree[k].children[j],tree,particles)
end
return tree
end
However, I cannot see where the infinite loop appears. Sorry for bringing these all here in a such form, I just want to avoid XY-problem.
Thank you in advance!

Index Exceeds Matrix Dimensions - Canny Edge Detection

I am using the following lines of code for edge detection using canny edge detector :
I=imread('bradd.tif');
figure,imshow(I);
IDtemp = im2double(I);
[r c]=size(I);
ID(r,c) = 0;
IDx(r,c) = 0;
IDfil(r,c) = 0;
IDxx(r,c) = 0;
IDy(r,c) = 0;
IDyy(r,c) = 0;
mod(r,c) = 0;
for i= 1 : r+4
for j = 1:c+4
if(i<=2 || j<=2 || i>=r+3 || j>=c+3)
ID(i,j) = 0;
else
ID(i,j) = IDtemp(i-2,j-2);
end;
end
end
%figure,imshow(ID);
filter=[2 4 5 4 2;4 9 12 9 4;5 12 15 12 5;4 9 12 9 4;2 4 5 4 2];
for i=1:5
for j=1:5
filter(i,j)=filter(i,j)/159;
end
end
%figure,imshow(filter);
for v = 3 : r
for u = 3 : c
sum = 0;
for i = -2 : 2
for j = -2 : 2
sum = sum + (ID(u+i, v+j) * filter(i+3, j+3));
end
end
IDx(u,v) = sum;
end
end
%figure,imshow(IDx);
IDxtemp = IDx;
for i= 1 : r+2
for j = 1:c+2
if(i<=1 || j<=1 || i>=r || j>=c)
IDfil(i,j) = 0;
else
IDfil(i,j) = IDxtemp(i-1,j-1);
end;
end
end
%figure,imshow(IDfil);
Mx = [-1 0 1; -2 0 2; -1 0 1]; % Sobel Mask in X-Direction
My = [-1 -2 -1; 0 0 0; 1 2 1]; % Sobel Mask in Y-Direction
for u = 2:r
for v = 2:c
sum1 = 0;
for i=-1:1
for j=-1:1
sum1 = sum1 + IDfil(u + i, v + j)* Mx(i + 2,j + 2);
end
end
IDxx(u,v) = sum1;
end;
end
%figure,imshow(IDxx);
for u = 2:r
for v = 2:c
sum2 = 0;
for i=-1:1
for j=-1:1
sum2 = sum2 + IDfil(u + i, v + j)* My(i + 2,j + 2);
end
end
IDyy(u,v) = sum2;
end
end
%figure,imshow(IDyy);
for u = 1:r
for v = 1:c
mod(u,v) = sqrt(IDxx(u,v)^2 + IDyy(u,v)^2) ;
%mod(u,v) = sqrt(IDxx(u,v)^2 + IDyy(u,v)^2);
end
end
%figure,imshow(mod);
modtemp = mod;
for i= 1 : r+2
for j = 1:c+2
if(i<=1 || j<=1 || i>=r || j>=c)
mod(i,j) = 0;
else
mod(i,j) = modtemp(i-1,j-1);
end;
end
end
%figure,imshow(mod);
theta(u,v) = 0;
supimg(u,v) = 0;
ntheta(u,v) = 0;
for u = 2 : r
for v = 2 : c
theta(u,v) = atand(IDyy(u,v)/IDxx(u,v));
if ((theta(u,v) > 0 ) && (theta(u,v) < 22.5) || (theta(u,v) > 157.5) && (theta(u,v) < -157.5))
ntheta(u,v) = 0;
end
if ((theta(u,v) > 22.5) && (theta(u,v) < 67.5) || (theta(u,v) < -112.5) && (theta(u,v) > -157.5))
ntheta(u,v) = 45;
end
if ((theta(u,v) > 67.5 && theta(u,v) < 112.5) || (theta(u,v) < -67.5 && theta(u,v) > 112.5))
ntheta(u,v) = 90;
end
if ((theta(u,v) > 112.5 && theta(u,v) <= 157.5) || (theta(u,v) < -22.5 && theta(u,v) > -67.5))
ntheta(u,v) = 135;
end
if (ntheta(u,v) == 0)
if (mod(u, v) > mod(u, v-1) && mod(u, v) > mod(u, v+1))
supimg(u,v) = mod(u,v);
else supimg(u,v) = 0;
end
end
if (ntheta(u,v) == 45)
if (mod(u, v) > mod(u+1, v-1) && mod(u, v) > mod(u-1, v+1))
supimg(u,v) = mod(u,v);
else supimg(u,v) = 0;
end
end
if (ntheta(u,v) == 90)
if (mod(u, v) > mod(u-1, v) && mod(u, v) > mod(u+1, v))
supimg(u,v) = mod(u,v);
else supimg(u,v) = 0;
end
end
if (ntheta(u,v) == 135)
if (mod(u, v) > mod(u-1, v-1) && mod(u, v) > mod(u+1, v+1))
supimg(u,v) = mod(u,v);
else supimg(u,v) = 0;
end
end
end
end
%figure,imshow(ntheta);
th = 0.2;
tl = 0.1;
resimg(u,v)= 0;
for u = 2 : r-1
for v = 2 : c-1
if(supimg(u,v) > th)
resimg(u,v) = 1;
else
if(supimg(u,v) >= tl && supimg(u,v) <= th )
resimg(u,v) = 1;
else
if (supimg(u,v) < tl)
resimg(u,v) = 0;
end
end
end
if (supimg(u-1,v-1) > th || supimg(u,v-1) > th || supimg(u+1,v-1) > th || supimg(u+1,v) > th || supimg(u+1,v+1) > th || supimg(u,v+1) > th || supimg(u-1,v+1) > th || supimg(u-1,v) > th)
resimg(u,v) = 1;
else
resimg(u,v) = 0;
end
end
end
figure,imshow(supimg);
figure,imshow(resimg);
However, for some of the images it is working fine, while for others it is showing the following error :
Index exceeds matrix dimensions.
Error in canny_edge (line 45)
sum = sum + (ID(u+i, v+j) * filter(i+3, j+3));
Can someone help me sort out this problem ??
Thanks and Regards.
Your loop ranges are in the wrong order leading to the error. If you modify your loop ranges to this
for u = 3 : r
for v = 3 : c
sum = 0;
for i = -2 : 2
for j = -2 : 2
sum = sum + (ID(u+i, v+j) * filter(i+3, j+3));
end
end
IDx(u,v) = sum;
end
end
the problem is solved.
My guess is that the code worked only for square images with c==r.
Note you are not making use of Matlab's vectorization capability, which allows you to shorten the first steps to:
ID = [zeros(2,c+4) ; [zeros(r,2) IDtemp zeros(r,2)]; zeros(2,c+4)];
filter=[2 4 5 4 2;4 9 12 9 4;5 12 15 12 5;4 9 12 9 4;2 4 5 4 2];
filter=filter/159;
for u = 1 : r
for v = 1 : c
IDx(u,v) = sum(reshape(ID(u+[0:4], v+[0:4]).* filter,25,1));
end
end
and this last loop can also be collapsed further but that might make readability an issue.
(edit) The loop can (for instance) be replaced with
IDx = conv2(ID, filter,'same');

Performance issues with LINQ query when including OR clause

The following LINQ to Entities query slows down substantially when the commented line below is included in the query. Is there a better way to phrase this?
The 'OR' clause should only take into account the following lines:
((o.Type_ID == (int) RecordEnums.RecordType.Lead) && (o.Item_ID == l1.Lead_ID))
|| ((o.Type_ID == (int)RecordEnums.RecordType.Opportunity)(o.Item_ID == o1.Opportunity_ID))
Full Query
return withItemsPending
? (from l1 in db.Leads
from o1 in db.Opportunities.Where(x => (x.Lead_ID == l1.Lead_ID) && (x.Company_ID == companyId)).DefaultIfEmpty()
from l2
in
db.Tasks.Where(
o =>
((o.IsCompleted ?? false) == false) &&
(o.TaskType_ID == typeId) &&
((o.Type_ID == (int) RecordEnums.RecordType.Lead) && (o.Item_ID == l1.Lead_ID))
//|| ((o.Type_ID == (int)RecordEnums.RecordType.Opportunity) && (o.Item_ID == o1.Opportunity_ID))
&&
(o.Due_Date > EntityFunctions.AddDays(DateTime.Now, -1)))
where (l1.Company_ID == companyId)
select l1)
: (from l1 in db.Leads where (0 == 1) select l1);
}
Here's the offending query:
SELECT Extent1.Lead_ID
FROM Leads AS Extent1 LEFT OUTER JOIN
Opportunities AS Extent2 ON Extent2.Lead_ID = Extent1.Lead_ID AND Extent2.Company_ID = 118 INNER JOIN
Tasks AS Extent3 ON 0 = (CASE WHEN ([Extent3].[IsCompleted] IS NULL) THEN CAST(0 AS bit) ELSE [Extent3].[IsCompleted] END) AND Extent3.TaskType_ID = 1 AND
5 = Extent3.Type_ID AND Extent3.Item_ID = Extent1.Lead_ID OR
4 = Extent3.Type_ID AND Extent3.Item_ID = Extent2.Opportunity_ID AND Extent3.Due_Date > DATEADD(day, - 1, SysDateTime())
WHERE (Extent1.Company_ID = 118)
If what you want is "give me the items that are not completed AND are due later than yesterday AND are EITHER Lead OR Opportunity", you need to add extra brackets around the 2 statements you want to OR. What you are currently saying is "give me the items that are either not completed AND Lead OR Opportunity AND due later than yesterday".
The code will then be like this:
return withItemsPending
? (from l1 in db.Leads
from o1 in db.Opportunities.Where(x => (x.Lead_ID == l1.Lead_ID) && (x.Company_ID == companyId)).DefaultIfEmpty()
from l2
in
db.Tasks.Where(
o =>
((o.IsCompleted ?? false) == false) &&
(o.TaskType_ID == typeId) &&
(((o.Type_ID == (int) RecordEnums.RecordType.Lead) && (o.Item_ID == l1.Lead_ID))
|| ((o.Type_ID == (int)RecordEnums.RecordType.Opportunity) && (o.Item_ID == o1.Opportunity_ID)))
&&
(o.Due_Date > EntityFunctions.AddDays(DateTime.Now, -1)))
where (l1.Company_ID == companyId)
select l1)
: (from l1 in db.Leads where (0 == 1) select l1);
}

Elegant algorithm to detect overlapping periods with unbounded ends

My question is the same as Algorithm to detect overlapping periods.
But in my case, a period can be unbouded (No End Date, ie. NULL).
I can't find an elegant way do to that.
For unbounded end dates, you could also do something like:
a.end = a.end == NULL ? MAXDATE : a.end;
b.end = b.end == NULL ? MAXDATE : b.end;
bool overlap = a.start < b.end && b.start < a.end;
Or this could work:
bool overlap = (a.start < b.end || b.end == NULL) && (b.start < a.end || a.end == NULL);

Resources