Why is my where condition in Linq query not working properly? - c#

I have a linq query where i have the following where condition:
where obj.DATUMREAL == date && (real == 2 ? true : (obj.ZAPKONC == null ? 0 : ((bool)obj.ZAPKONC ? 1 : 0)) == real)
If I set parameter real to 2, it works normally, but if I set it to 1 or 0 the where statement just ignores the first condition obj.DATUMREAL == date and it only filters with the second part after the &&.
Here is the whole query:
var result = (from obj in entities.OBJKVPOPLANU
where obj.DATUMREAL == date
&& (real == 2 ?
true : (obj.ZAPKONC == null ? 0
: ((bool)obj.ZAPKONC ? 1 : 0)) == real)
group obj by obj.VODSISTEM into objg
join v in entities.SIVODSISTEM
on objg.FirstOrDefault().VODSISTEM equals v.SIFRA.ToString()
into vj
from subpet in vj.DefaultIfEmpty()
select new
{
subpet.SIFRA,
STEV = objg.Count(),
subpet.NAZIV
}).ToList();
return result;
If I set real value to 2 I get 30 items returned which are filtered by the first part of where, but if I set it to 1 or 0 I get more items that completely ignore the first part of where.
UPDATE
I solved it by swapping the two parts of the where statement around. I don't know what the issue was

Related

simple SQL query to LinQ , i have tried but not solved yet

I have the following SQL Server query and I need to have it in LINQ, Simple query but I tried several time but I can not get it working.
Here is the SQL query
select *
from td_Accountline
where
BonusPlanID = 1
and Amount > 0
and Ord_Sub_ID like '%SMPORD%'
and MONTH(Created) = 11
and YEAR(Created) = 2013
and Ord_Sub_ID not in (
select Ord_Sub_ID
from td_Accountline
where
BonusPlanID =3 and
Ord_Sub_ID like '%SMPORD%'
)
I have tried with this query but still i am confused
var account=from acc in currentDB.td_Accountline
where acc.BonusPlan.BonusPlanID == 1 && acc.Amount > 0 && acc.Ord_Sub_ID.Contains("SMPORD") && acc.Created.ToDateTime().Month == 11 && acc.Created.ToDateTime().Year == 2013
let accNot = from accN in currentDatabase.td_Accountline
where accN.BonusPlan.BonusPlanID == 3 && accN.Ord_Sub_ID.Contains("SMPORD")
select accN.Ord_Sub_ID
where !accNot.Contains("SMPORD")
select acc;
I want one query please not separate query to reduce database calling.
I think you're almost there. Instead of:
where !accNot.Contains("SMPORD")
It should be:
where !accNot.Contains(acc.Ord_Sub_ID)
Your final Linq query would be:
var account = from acc in currentDB.td_Accountline
where
acc.BonusPlan.BonusPlanID == 1
&& acc.Amount > 0
&& acc.Ord_Sub_ID.Contains("SMPORD")
&& acc.Created.Month == 11
&& acc.Created.Year == 2013
let accNot = from accN in currentDatabase.td_Accountline
where
accN.BonusPlan.BonusPlanID == 3
&& accN.Ord_Sub_ID.Contains("SMPORD")
select accN.Ord_Sub_ID
where !accNot.Contains(acc.Ord_Sub_ID)
select acc;
Regular Expressions won't work in Linq for Entity Framework but you can convert to collection in an in-memory list for you to use Regex.
Something like this:
(from x in td_Accountline where Created.Month = 11 && Created.Year = 2013 select a).ToList().Where(v => Regex.IsMatch(v.Ord_Sub_ID,#"(SMPORD)"))
That way, the match will happen in memory
Try This :
var Ord_Sub_IDs = from n in td_Accountline where n.BonusPlanID == 3 && n.Ord_Sub_ID.Contains("SMPORD") select n.Ord_Sub_ID ;
var result=from n in td_Accountline where n.BonusPlanId == 1 && n.Amount > 0 && n.Ord_Sub_ID.Contains("SMPORD") && n.Created.ToDateTime().Month == 11 && n.Created.ToDateTime().Year == 2013 && Ord_Sub_IDs.Contains(td.Ord_Sub_ID) select n;

LINQ join taking a lot of time

I am currently using the following linq query
lsttask = (from d in administrationEntities.Tasks
.Include("Status")
.Include("Priority")
.Include("Batch")
.Include("Batch.ShipmentGroup")
.Include("Batch.ShipmentGroup.Shipment")
.Include("Batch.ShipmentGroup.Shipment.TOCShipmentManifests.TOCShipmentDetails.TOCShipmentProcesses")
.Include("Batch.ShipmentGroup.Shipment.Project")
.Include("TaskType")
where ((projectId == null ? true : d.Batch.ShipmentGroup.Shipment.Project.ProjectId == projectId)
&& ( statusId == null ? true : d.StatusId == statusId)
&& d.IsDeleted == false)
select d)
.ToList();
but its really consuming time , like up to 30 plus seconds
Is there an alternate way to trim on the execution time?

Filter Generic List by multiple values

There is a generic list of documents, how can i filter it by doc id 1 and 2.
I have tried following Linq but it is not working. I need to filter list and use it as a data source.
List<VisitDocs> listD = default(List<VisitDocs>);
result = from docs in listDwhere docs.DocID == 1 && docs.DocID == 2docs;
rptDocs.DataSource = listD;
You need ||:
result = listD.Where(doc=> doc.DocID == 1 || doc.DocID == 2);
or
result = from docs in listD where docs.DocID == 1 || docs.DocID == 2 select docs;
Your DocID could be 1 or 2, It can't be both. Your current condition is using && which would mean that it must be 1 and 2 at the same time.
For assigning DataSource call ToList like:
rptDocs.DataSource = result.ToList();
docs.DocID == 1 && docs.DocID == 2 can never be true: if the value is 1, it's not 2, and vice versa. You need to use || (or), not && (and)
Please, change && to || and see if it works
I think you tried to write something like this :
var result = (from docs in listD
where docs.DocID == 1 || docs.DocID == 2
select docs).ToList();
rptDocs.DataSource = result;
Where listD is your original list. Please note that in your code sample, ListD will be empty.
If you wish results with both DocID values 1 and 2, simply replace "&&" by "||". With "&&" it means that any single result should valid both conditions, which is impossible : a single result will have DocID equals to 1, or 2, or anything else. So if you want to take every result with 1 "or" 2, you should use the OR logical operator.

Use Linq to search through list

Is it possible to use a Linq query to search through a List? In my web app I have to potentially process over 14k records based upon a spreadsheet uploaded by the user. With each record processed, I need to compare that record against what we currently have in our database in order to make sure we either aren't adding a duplicate or I know what record I need to be updating/editing.
Instead of hitting the database 14k times or more, I wanted to pull all the records contained on this table into a List, and then perform a search based on a set of conditions.
Here is the Linq query I currently have that hits the database. The business rules are pretty... complicated so I won't bother you with the details but these are the conditions that I need to satisfy for the search. I've tested this query and it returns the expected results.
var previousZips = (from z in db.ZipCodeTerritory
where (item.ZipCode.Equals(null) ?
z.StateCode.Equals(item.StateCode) &&
z.ChannelCode.Equals(item.ChannelCode) &&
SqlFunctions.DateDiff("DAY", z.EndDate, item.EndDate) == 0 :
z.StateCode.Equals(item.StateCode) &&
z.ChannelCode.Equals(item.ChannelCode) &&
SqlFunctions.DateDiff("DAY", z.EndDate, item.EndDate) == 0 &&
(z.ZipCode.Equals(null) || z.ZipCode.Equals(item.ZipCode)))
select z).ToList();
What I would like to do, however, is create a List of all the records on the table like this:
List<ZipCodeTerritory> allRecords = (from z in db.ZipCodeTerritory
select z).ToList()
and then use a query similar to this to pull the record I'm looking for from the list:
List<ZipCodeTerritory> previousZips = allRecords.Where(
z => (item.ZipCode.Equals(null)
? z.StateCode.Equals(item.StateCode) &&
z.ChannelCode.Equals(item.ChannelCode) &&
SqlFunctions.DateDiff("DAY", z.EndDate,
item.EndDate) == 0
: z.StateCode.Equals(item.StateCode) &&
z.ChannelCode.Equals(item.ChannelCode) &&
SqlFunctions.DateDiff("DAY", z.EndDate,item.EndDate) == 0 &&
(z.ZipCode.Equals(null) || z.ZipCode.Equals(item.ZipCode))
)
).ToList();
The query above (from the List), however, throws the following error:
This function can only be invoked from LINQ to Entities.
Answered my own question. The problem here was the SqlFunction. By removing that from the query and re-writing it like this it works
List<ZipCodeTerritory> previousZips = allRecords.Where(
z => (item.ZipCode.Equals(null)
? z.StateCode.Equals(item.StateCode) &&
z.ChannelCode.Equals(item.ChannelCode) &&
z.EndDate.Date == item.EndDate.Date
: z.StateCode.Equals(item.StateCode) &&
z.ChannelCode.Equals(item.ChannelCode) &&
z.EndDate.Date == item.EndDate.Date &&
(z.ZipCode.Equals(null) || z.ZipCode.Equals(item.ZipCode))
)
).ToList();
Instead of
SqlFunctions.DateDiff("DAY", z.EndDate,item.EndDate) == 0
use
z.EndDate.Subtract(item.EndDate).TotalDays == 0

Operator '!=' cannot be applied to operands of type 'bool?' and 'int'

I am getting the above error when I am trying to run my query in Linq Pad which is as below,
var qry = (from i in INTERNETDATAs
join c in COVERS on Convert.ToInt32(i.COVERTYPE) equals c.COV_TYPE
where i.DATELOADED >= new DateTime(2013,7,1)
&& i.DATELOADED < new DateTime(2013,8,1)
&& i.CAMPAIGNTYPE == "4"
&& c.COVERTYPEID == 17063789
&& c.CHILDAPPLIES != 1
&& c.SPOUSEAPPLIES != 1
select i
);
qry.Dump();
The column c.CHILDAPPLIES and c.SPOUSEAPPLIES in my COVERS table are of (bit, null) type.
My Sql query is working fine which as below but my LINQ query gives error Operator '!=' cannot be applied to operands of type 'bool?' and 'int'
SELECT Count(*)
FROM INTERNETDATA I Join COVERS C ON C.COV_TYPE = CONVERT(int, I.COVERTYPE)
WHERE ((I.DATELOADED >= CONVERT(DATETIME, '1 Jul 2013 00:00:00'))
AND (I.DATELOADED < CONVERT(DATETIME, '1 Aug 2013 00:00:00')))
AND (CONVERT(int, I.COVERTYPE) = C.COV_TYPE)
AND (C.COVERTYPEID = 17063789)
AND (I.CAMPAIGNTYPE = 4)
AND C.CHILDAPPLIES != 1
AND C.SPOUSEAPPLIES !=1
Thanks in advance.
I suspect you just want:
&& !c.CHILDAPPLIES
&& !c.SPOUSEAPPLIES
... although you should consider whether you want this to match rows where the columns are NULL rather than true or false. If the above doesn't compile (which it may not) you can effectively provide the "default" value with the null-coalescing operator:
&& !(c.CHILDAPPLIES ?? true)
&& !(c.SPOUSEAPPLIES ?? true)
or
&& !(c.CHILDAPPLIES ?? false)
&& !(c.SPOUSEAPPLIES ?? false)
The problem is that in the LINQ mapping, they're not "0 or 1" values - they're "true or false" values (or null) - so you can't compare them with integers.
try following i think this what you want
var qry = (from i in INTERNETDATAs
join c in COVERS on Convert.ToInt32(i.COVERTYPE) equals c.COV_TYPE
where i.DATELOADED >= new DateTime(2013,7,1)
&& i.DATELOADED < new DateTime(2013,8,1)
&& i.CAMPAIGNTYPE == "4"
&& c.COVERTYPEID == 17063789
&& c.CHILDAPPLIES != true
&& c.SPOUSEAPPLIES != true
select i
);
qry.Dump();
I would suggest it is one of these 2:
&& c.CHILDAPPLIES != 1
&& c.SPOUSEAPPLIES != 1
Even though they are of type Bit linq will compare them as boolean
If it returns bool? couldn't You just compare it with True or False?
Instead of CHecking it using '!=' Operator,Use
!c.CHILDAPPLIES && !c.SPOUSEAPPLIES.
This Might help

Categories

Resources