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

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;

Related

Entity Framework query similar to raw SQL query with order by date where null comes last

l have a query
SELECT *
FROM [ExcelDumps].[dbo].[ProductPrice] As p
Where
(
p.[EndDate] >= '2018-12-18'
OR
p.[EndDate] is null
)
order by case when p.[EndDate] is null then 2 else 1 end, p.[EndDate] asc
what am trying to achieve is it possible to achieve the same results using Entity Framework where priority is lastly given to p.[EndDate]
the desired output is as follows :
what l have done
using (var cod = new ExcelDumpsEntities1())
{
var list = cod.ProductPrices.Where(c => c.EndDate >= c.EndDate || c.EndDate == null)
.OrderBy(c => c.EndDate)
.FirstOrDefault();
var sqlQuery = #"SELECT Top 1 *
FROM [ExcelDumps].[dbo].[ProductPrice] As p
Where
(
p.[EndDate] >= '2018-12-18'
OR
p.[EndDate] is null
)
order by case when p.[EndDate] is null then 2 else 1 end, p.[EndDate] asc ";
var sqlRaw = cod.ProductPrices.SqlQuery(sqlQuery)
.FirstOrDefault();
}
Console.ReadLine();
I don't want to use SQL query or stored procedure but must do it in like LINQ to entities
this question is based on this question on dba sql query here
How can l do that in Entity Framework
var filterDate = new DateTime("2018-12-18");
var result = cod.ProductPrices.Where(c => c.EndDate >= filterDate || c.EndDate == null)
.OrderBy(c => c.EndDate == null)
.ThenBy(c => c.EndDate);
If you want to execute the query immediately you might want to add an .ToList() in the end. Otherwise it will be executed when it is used.

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?

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

"LINQ to Entities does not recognize the method" when Convert to Int 32

Before post this question i try search based on my problem i couldn't find one (may be am not search that well :(, i was trying to convert my string to integer in the linq query i got this exception.
**
LINQ to Entities does not recognize the method 'Int32
ToInt32(System.String)' method, and this method cannot be translated
into a store expression
**
Posting full query might be time wasting for you guys so i just dropped the main line where i get stuck
int intBookingNumber = Convert.ToInt32(Booktime);
var query =
(from PROJECTS in db.PROJECTS
join WOes in db.WOes on PROJECTS.PRJ_ID equals WOes.PRJ_ID
join SEVTs in db.SEVTs on WOes.SEQNUM equals SEVTs.SEQNUM
join RSRCEs in db.RSRCEs on SEVTs.RESID equals RSRCEs.RESID
join PERS in db.PERS on RSRCEs.RECID equals PERS.RECID into PERS_join
from PERS in PERS_join.DefaultIfEmpty()
join RESTYPEs in db.RESTYPEs on new { RTYPE = SEVTs.RTYPE } equals new { RTYPE = RESTYPEs.CODE }
join RESCATs in db.RESCATs on new { RCAT = SEVTs.RCAT } equals new { RCAT = RESCATs.CODE }
join SEVT_EX in db.SEVT_EX on SEVTs.SESID equals SEVT_EX.SESID into SEVT_EX_join
from SEVT_EX in SEVT_EX_join.DefaultIfEmpty()
where
(new string[] { "1", "2" }).Contains((PROJECTS.STAT.TrimEnd()).TrimStart()) &&
(WOes.STAT.TrimEnd()).TrimStart() == "6" &&
((SEVTs.RESTYPE == 5 ||
SEVTs.RESTYPE == 0) &&
(RESTYPEs.USER2.Substring(2 - 1, 1) == "F" &&
RESTYPEs.USER2.Substring(6 - 1, 1) == "S") &&
SEVTs.TYPE == 0) ||
(SEVTs.RESTYPE == 4 &&
SEVTs.TYPE == 0) &&
RESCATs.GROUPID==0 &&
RESTYPEs.GROUPID==0 &&
(int?)(WOes.INVOICE.TrimStart()).Length > 0 &&
WOes.INVOICE.TrimStart() != "PENDING" &&
WOes.USERFLAG1 != 1 &&
//(SEVTs.T_START.TrimStart()) == (Booktime)
//Convert.ToInt32(SEVTs.T_START.TrimStart()) >= Convert.ToInt32(Booktime)
Convert.ToInt32(SEVTs.T_START) >= intBookingNumber
orderby
PROJECTS.PRJ_ID,
WOes.WONUM
select new
{
PROJECTS.PRJ_ID,
PROJECTS.USER3,
PROJECTS.USER9,
WOes.WONUM,
WOes.JOBDESC,
SEVTs.SESID,
SEVTs.RESTYPE,
SEVTs.TYPE,
SEVTs.T_START,
SEVTs.T_END,
SEVTs.MEALEND,
SEVTs.MELSTART3,
SEVTs.MELSTART2,
SEVTs.MELEND2,
Column1 = SEVTs.MELSTART2,
SEVTs.MELEND3,
SEVTs.USER2,
SEVTs.SUBACTID,
SEVTs.OT_EXEMPT,
USER5 = SEVT_EX.USER5,
SEVTs.GMT_OFFSET,
SEVTs.MEALSTART,
SEVTs.STANDARD,
RESCATs.USER1,
SEVTs.RESID
});
SEVTs.T_START.TrimStart() and bookingStart both data types are string. Obviously they are getting numbers here . how can i use the logic operator here.
Any help much appreciated.
Find the work around guys, this help me to solve my problem
**String.Compare(SEVTs.T_START.TrimStart(), Booktime) >= 0**
Whats the actual DataType of the T_START? if Int and nullable this might be your solution. notice the .Value and .HasValue
Where ...
SEVTs.T_START.HasValue && (SEVTs.T_START.Value >= intBookingNumber)
...
Found the work around guys, this help me to solve my problem
**String.Compare(SEVTs.T_START.TrimStart(), Booktime) >= 0**

Categories

Resources