Need Equivalent LINQ Query for the following SQL Server Query - sql-server

I am looking for the equivalent LINQ query for the following Query.
SELECT SUM (Cost) FROM [Vulpith_Test2].[dbo].tbl_MilestonesForOngoingSeeker]
WHERE ([Post_Title_ID] = '3251'
and [List_Title_ID]='1180')
and (PaymentStatus='1' or PaymentStatus='3');

int sumofCost = dbContext.tbl_MilestonesForOngoingSeeker.Where(a => a.Post_Title_ID == "3251" && a.List_Title_ID == "1180" && (a.PaymentStatus == 1 || a.PaymentStatus == 3)).Sum(a => a.Cost);

Related

Why does LINQ generated SQL include multiple "IS NULL" conditions for the same column

The following query against a SQL Server 2012 database, using Entity Framework Core 3.1:
var tows = await _context.DataEntryTow
.Where(t => _context.DataEntrySample
.Any(s => s.TowId==t.TowId && (s.MicroscopeId != "0" || s.MicroscopeId == null)))
.Select (t => new { text = t.TowId, value = t.TowId });
generates this SQL:
SELECT d.tow_id AS text
FROM data_entry_tow AS d
WHERE EXISTS (
SELECT 1
FROM data_entry_sample AS d0
WHERE (d0.tow_id = d.tow_id) AND (((d0.microscope_id <> '0') OR (d0.microscope_id IS NULL)) OR (d0.microscope_id IS NULL)))
I don't think I've done anything wrong, and I'm fairly sure the query optimizer will eliminate the second (d0.microscope_id IS NULL), but it still seems like an error in the LINQ code.
MicroscopeId is defined:
public string MicroscopeId { get; set; }
Field MicroscopeId declared as nullable. So, to mimic LINQ to Objects behaviour when null != "0" is true but in SQL null <> '0' is false, EF Core generates additional OR condition.
To disable this geneeration you have to specify that when building DbContextOptions:
optionsBuilder.UseSqlServer(constr, b => b.UseRelationalNulls(true) );
Additional info: https://learn.microsoft.com/en-us/ef/core/querying/null-comparisons#using-relational-null-semantics

EF Core 3.1 produces incorrect query translation

I have the following EF Core 3.1 statement:
var orders = await _dbContext.Orders.Include(o => o.OrderReceivers)
.Where(o => o.BooleanFlag1 && o.OrderState == OrderState.SomeState && o.OrderReceivers.Any(o => o.BooleanFlag2))
.ToListAsync(cancellationToken);
and this is the generated SQL Server query:
SELECT /*All column names here*/
FROM [Schema].[Orders] AS [o]
LEFT JOIN [Schema].[OrderReceivers] AS [o0] ON [o].[Id] = [o0].[OrderId]
WHERE (([o].[ShouldSendBlackList] = CAST(1 AS bit)) AND ([o].[OrderState] = 2)) AND EXISTS (
SELECT 1
FROM [Schema].[OrderReceivers] AS [o1]
WHERE ([o].[Id] = [o1].[OrderId]) AND ([o1].[BooleanFlag2] = '1'))
ORDER BY [o].[Id], [o0].[Id]
The problem with the generated SQL Query is this part:
([o1].[BooleanFlag2] = '1')
Because this causes the second where clause to be always false!
Any ideas on what is wrong here? Thanks in advance.

Linq - Query on 2 Lists Optimization

I am having 2 Lists & I am querying on this 2 List. Both the List are populated with huge data. So the query is taking long time.
When I usually face this performance issue, I simply convert SQL queries & run them directly & get the result in a datatable. But this time I cannot do this as these 2 are not tables but Lists of Models.
How to Optimize this Query or what else should i do?
Code :-
List<TempInOut> listTempInOut = new List<TO_TempInOut>();
List<ShiftSchedule> tempShiftSch = new List<TO_TempInOut>();
var data = (from B in tempShiftSch
from C in listTempInOut
where
B.CompanyId == companyId &&
C.CompanyId == companyId &&
B.EmployeeId == C.EmployeeId &&
C.InDate >= StrOutStart &&
C.InDate <= StrOutEnd &&
B.ShiftId == item.ShiftCode &&
B.ShiftDate == tempInputDate
select new
{
C.EmployeeId,
C.InDate,
C.Time_Date1
}).ToList();
Implement an IEqualityComparer for your types, use HashSet for each collection, and use the HashSet.Intersect method to get your output.
You can simplify your query to two stepsand compare time.
I am thinking of something like that.
var listTempInOutResult = listTempInOut.Where(C => C.CompanyId == companyId
&& C.InDate >= StrOutStart
&& C.InDate <= StrOutEnd);
var employessIds = listTempInOutresult.Select(x => x.EmployeeId).ToList();
var data = tempShiftSch.Where(B => employessIds.Contains(B.EmployeeId)
&& B.CompanyId == companyId
&& B.ShiftDate == tempInputDate
&& B.ShiftId == item.ShiftCode)
.Select(C=> new
{
C.EmployeeId,
C.InDate,
C.Time_Date1
}).ToList();
if you are working with iqueryable it would be better to use joins.
see this StackOverflow question

LINQ equivalent of my SQL Query for UNION ALL

(SELECT * FROM SheetHay WHERE SheetStatus = 2)
UNION ALL(SELECT * FROM SheetHay WHERE SheetStatus = 1)
UNION ALL (SELECT * FROM SheetHay WHERE SheetStatus = 0)
UNION ALL(SELECT * FROM SheetHay WHERE SheetStatus= 3)
I get result set like this:
I mean I get all '2' together, '0' together, '3' together ( no '1' in
table yet). But when I use LINQ and UNION them I see the result on my grid in order of SheetID, the primary key. I mean I see the order of sheets displayed as 15,23,25,27,28,29 etc. But I want it just as the SQL result set.23,43,25,28 etc
IEnumerable<SheetHay> listTwos = Get(LINQ QUERY TO GET just twos);
IEnumerable<SheetHay> listOnes = Get(LINQ QUERY TO GET just Ones);
IEnumerable<SheetHay> listZeros = Get(LINQ QUERY TO GET just Zeros);
IEnumerable<SheetHay> listThrees = Get(LINQ QUERY TO GET just Threes);
....
return listTwos.Union(listZeros).Union(listOnes).Union(listThrees);
Let me know if you need any other information. Thanks.
You don't need to use multiple queries you can use CASE in the ORDER BY in sql and a similar way in LINQ.
SQL:
SELECT * FROM SheetHay
WHERE SheetStatus IN(0,1,2,3))
ORDER BY CASE SheetStatus
WHEN 2 THEN 1
WHEN 1 THEN 2
WHEN 0 THEN 3
WHEN 3 THEN 4 END ASC, SheetStatus ASC
LINQ:
int[] status = {0, 1, 2, 3};
var query = db.SheetHay
.Where(s => status.Contains(s.SheetStatus))
.OrderByDescending(s => s.SheetStatus == 2)
.ThenByDescending(s => s.SheetStatus == 1)
.ThenByDescending(s => s.SheetStatus == 0)
.ThenByDescending(s => s.SheetStatus == 3)
.ThenBy(s => s.SheetStatus);
Descending because a comparison returns bool and true is "higher" than false(1/0).
You could also use a conditional operator to return an int for the ordering:
var query = db.SheetHay
.Where(s => status.Contains(s.SheetStatus))
.OrderBy(s => s.SheetStatus == 2 ? 0 : 1)
.ThenBy(s => s.SheetStatus == 1 ? 0 : 1)
.ThenBy(s => s.SheetStatus == 0 ? 0 : 1)
.ThenBy(s => s.SheetStatus == 3 ? 0 : 1)
.ThenBy(s => s.SheetStatus);
What about this:
IEnumerable<SheetHay> sheetHays =
SheetHays
.Where(x => x.SheetStatus < 3)
.OrderByDescending(x => x.SheetStatus)
.Concat(SheetsHays.Where(x => x.SheetStatus == 3));
This is based on order 2, 1, 0, 3 (which is what you example query demonstrates). This will need to be modified if you want order 2, 0, 1, 3 (which is what you sample code implies).

Linq contains()

I am implementing a search button, that pulls all products having the words a user will be entering in a textbox.
Say the user types : Shoes.
I coded my linq to query the database to return all product containing the keyword in any of its columns as below
var products = from x in db.Products
where x.SupplierId == loggedInUser &&
( x.Status.ToString().Contains(searchCriteria) ||
x.SupplierCode.Contains(searchCriteria) ||
x.ProductId.ToString().Contains(searchCriteria) ||
x.Barcode.Contains(searchCriteria) ||
x.Description.Contains(searchCriteria) ||
x.ProposedActiveDate.ToString().Contains(searchCriteria) ||
x.VATRate.ToString() .Contains(searchCriteria) )
select x;
Problem ?
I do not get any product from the database(There is the product in the database).
What did I do wrong ?
I think you have the order wrong...
if the user had typed shoes, boots then you need to split the search terms "shoes" and "boots" and add them to a list<> and then do the following
SearchTermsList.Contains(x.Status.ToString()) || SearchTermsList.Contains(x.SupplierCode)
var searchCriteriaLowerCase = lowerCase.ToLower();
var products = db.Products.Where(x=> x.SupplierId == loggedInUser &&
x.Status.ToLower().ToString().Contains(searchCriteriaLowerCase) ||
x.SupplierCode.ToLower().Contains(searchCriteriaLowerCase) ||
x.ProductId.ToLower().ToString().Contains(searchCriteriaLowerCase) ||
x.Barcode.ToLower().Contains(searchCriteriaLowerCase) ||
x.Description.ToLower().Contains(searchCriteriaLowerCase) ||
x.ProposedActiveDate.ToString().Contains(searchCriteria) ||
x.VATRate.ToLower().ToString().Contains(searchCriteria) ).ToList();
This may work.
I think you are not executing the query.
use like this.
var products = from x in db.Products
where x.SupplierId == loggedInUser &&
( x.Status.ToString().Contains(searchCriteria) ||
x.SupplierCode.Contains(searchCriteria) ||
x.ProductId.ToString().Contains(searchCriteria) ||
x.Barcode.Contains(searchCriteria) ||
x.Description.Contains(searchCriteria) ||
x.ProposedActiveDate.ToString().Contains(searchCriteria) ||
x.VATRate.ToString() .Contains(searchCriteria) )
.ToList();

Resources