I am trying to create a where clause in Linq to SQL using the following logic
if #supplierid is null return all records.
if #supplierid is not null return where supplierid is equals to #supplierid.
and the one that is creating an issue:
if #supplierid ==0 return all records where supplierid is null
I tried writing this like
var answers =
from thisChargeableService in this.GetAll()
where
(
(
(supplierId == null) ||
(
((supplierId < 1) && (thisChargeableService.SupplierId == null)) ||
((supplierId != null) && (thisChargeableService.SupplierId == supplierId.Value))
)
));
This works with the first two conditions but when #supplierid = 0, nothing is returned.
Any help with this would be much appreciated
edit
Basically I have a dropdown of N/A with an id of 0. I have used this to identify that an option has been selected from dropdown and the user is targeting all rows where the supplier id is N/A.
The database contains no entries with 0 as the supplierid, so instead I am trying to target this with where the supplierid is null or the below in SQL
SELECT * FROM ChargeableService
WHERE
(#supplierid is null)
OR
(
(#supplierid is not null and supplierid = #supplierid) or
(#supplierid = 0 AND supplierid is null)
)
With Linq, there is no need to try to build one query to do all. Instead you can build your expression in buts and let deferred execution build and execute the correct sql.
So, this is the way I would do it.
var answers = this.GetAll().AsQueryable();
if (supplierId.HasValue && (supplierId.Value != 0))
answers = answers.Where(a=>a.SupplierId == supplierId.Value);
if (supplierId.HasValue && (supplierId.Value == 0))
answers = answers.Where(a=>!a.SupplierId.HasValue);
I've taken your query and run it against some similar data and the following works:
var answers =
from thisChargeableService in this.GetAll()
where
(
supplierId == null ||
(supplierId == 0 && thisChargeableService.SupplierId == null) ||
(supplierId > 0 && thisChargeableService.SupplierId == supplierId)
)
select thisChargeableService;
Related
i am getting data from user table using linq in this table i have two field AgencyID (int) and MemberID (int) in table these fields are null values when i am calling data by using below query it does not find any record although it exists, reason is that this part (Where(x.AgencyID== null && x.MemberID == null) have to be pass '0' instead of null how i convert it into zero
i have tried
return View(db.vt_Users.Where(x => x.IsDeleted != true &&
x.AgencyID == null &&
x.MemberID == null)
.ToList());
I try to convert SQL to LINK query
I try this
SQL query
Select name, count(*) from tblVehicles
WHERE MID = 23065 and name<> '' Group By name
LINQ query
var re = (from vehvoila in DB.tblVehicles
where vehvoila.MID='23065' && vehvoila.name
group vehvoila by new{vehvoila.name} into g
select new
{
g.Key.name,
cnt=g.Select(t=>t.name).Count()
});
How I use <> in LINQ ?
What could work for you is
where vehvoila.MID == "23065" && !(vehvoila.name == null || vehvoila.name == "")
or just
where vehvoila.MID == "23065" && vehvoila.name != ""
String.IsNullOrEmpty in not supported in Linq-SQL:
Method 'Boolean IsNullOrEmpty(System.String)' has no supported translation to SQL.
Using: Entity Framework 4.3.1, MVC 4
Sample database records (for example):
Id Height
1 null
2 2.1
Why does this first statement bring back zero results:
decimal? scannedItemHeight = default(decimal?);
(from st in Stocks
where st.Height == scannedItemHeight
select st.Id).ToList();
But this statement returns record Id 1:
(from st in Stocks
where st.Height == null
select st.Id).ToList();
If scannedItemHeight is null, I only want to match values where the height is null too.
I only want to return the first record, Id 1.
UPDATE
I ended up using:
st.Height == scannedItemHeight || (scannedItemHeight == null && st.Height == null)
That's because in first case database query would be something like
where Height = #param1 ...
While in second case that would be
where Height is null
First query would return no results because #param1 would be null and no row can match such condition.
Main point is that from C# standpoint those queries are equivalent, but from sql standpoint they are not: you should use IS NULL (or IS NOT NULL) in sql to check for nulls.
How to fix depends on what do you want to do when your parameter is null. In your case: use Jon Skeet's answer.
If someone will want to ignore parameter and not filter by it at all(quite common case, for example when parameter represents user's input in some field, and when nothing is typed there - nothing to filter), then do:
where scannedItemHeight == null || st.Height == scannedItemHeight
which will be in sql like
where #param1 is null OR Height = #param1
I've certainly seen some odd LINQ behaviour before now, due to the way that SQL handles nulls not being the same as the way that C# handles nulls. In C#, a == b is true if a and b are both null, whereas in SQL they're not... instead you have to deliberately check for nullity. I would try:
var temp = (from st in Stocks
where st.Height == scannedItemHeight || (scannedItemHeight == null && st.Height == null)
select st.Id).ToList();
Or construct the queries differently:
var filtered = scannedItemHeight == null
? Stocks.Where(st => st.Height == null)
: Stocks.Where(st => st.Height == scannedItemHeight);
var temp = filtered.Select(st => st.Id).ToList();
I've been trying to modify some rows of data in SQL to test in my application and I've noticed my query in Lambda brings back 0 rows when I am expecting 2387 row. The source of the problem is I am using parenthesis in a WHERE clause in SQL to look at some null values. This is the SQL query:
SQL
-- THIS WORKS!
select * from vwAppsWithIssues
where fld1stCheckAllocatedTo = 'nicholasg' and fldStage = 1
and (fldStopStartDate is null or fldStopEndDate is not null)
-- The query was originally this (doesn't return rows)
select * from vwAppsWithIssues
where fld1stCheckAllocatedTo = 'nicholasg' and fldStage = 1
and (fldStopStartDate = null or fldStopEndDate <> null)
LAMBDA query that returns 0 rows
public static int GetApplicationsFirstCount(string UserId)
{
try
{
using (IME_CheckOffEntities IME_CheckOffEntities = new IME_CheckOffEntities())
{
return IME_CheckOffEntities.vwAppsWithIssues
.Where(a => a.fld1stCheckAllocatedTo == UserId && a.fldStage == 1 && (a.fldStopStartDate == null || a.fldStopEndDate != null))
.ToList().Count;
}
}
catch (Exception ex)
{
throw;
}
}
Update
Using LINQPad I have written this expression:
VwAppsWithIssues
.Where (v => v.Fld1stCheckAllocatedTo == "nicholasg"
&& v.FldStage == 1
&& (v.FldStopStartDate == null || v.FldStopEndDate != null)).Count()
that generates this sql
SELECT COUNT(*) AS [value]
FROM [vwAppsWithIssues] AS [t0]
WHERE ([t0].[fld1stCheckAllocatedTo] = #p0) AND ([t0].[fldStage] = #p1) AND (([t0].[fldStopStartDate] IS NULL) OR ([t0].[fldStopEndDate] IS NOT NULL))
So now that I have some lambda that I think will work, I simply copy it to visual studio.
var count = IME_CheckOffEntities.vwAppsWithIssues
.Where(v => v.fld1stCheckAllocatedTo == "nicholasg" && v.fldStage == 1 && (v.fldStopStartDate == null || v.fldStopEndDate != null)).Count();
It still returns only 0 rows?! I am passing in the right userId in C# as well.
My count in c# also returns 0 rows. Any idea how I can rewrite this C# query?
from linqpad, on one of my schema
from
f in Files
where
f.PubDate == null || f.FilingDate != null
select
f.IdFile
is translated as follow
SELECT
[Extent1].[idFichier] AS [idFichier]
FROM [dbo].[tableF] AS [Extent1]
WHERE ([Extent1].[datePubliF] IS NULL) OR ([Extent1].[dateDepotF] IS NOT NULL)
so, in your case, are you, for example, sure of the UserId value ?
I am trying to convert a complex (and rather hacky) dynamic SQL query in to a LINQ query.
I have the following LINQ query so far:
var results = (
from c in Customers
from d in MonthCalendar
join f in Facilities on c.CustomerCode equals f.CustomerCode
join p in ProjectedCashFlows on f.FacilityId equals p.FacilityId into pj
from p in pj.DefaultIfEmpty()
where d.ExpectedYear == currentYear
&& f.FacilityStatusId == 1
&& (p.ExpectedYear == null || d.ExpectedYear == p.ExpectedYear)
&& (p.ExpectedMonth == null || d.ExpectedMonth == p.ExpectedMonth)
&& c.PrimaryArmId == userId
&& (p.ProjectedCashFlowStatusId == null || p.ProjectedCashFlowStatusId != 4)
select new
{
CustomerCode = c.CustomerCode,
CustomerName = c.CustomerName,
FacilityId = f.FacilityId,
FacilityDescription = f.FacilityProductDescription,
FacilityCurrency = f.FacilityCurrencyId,
FacilityLimit = f.Limit,
ExpectedYear = d.ExpectedYear,
ExpectedMonth = d.ExpectedMonth,
ExpectedAmount = p == null ? 0 : (double)p.ExpectedAmount
}
);
I am trying to retrieve details from a Customer table that has a one-to-many relationship with a Facilities table. I am then trying to retrieve any details located in the ProjectedCashFlows
The problem I am having is that the query should return all Customer and Facilites information regardless of whether any values exist in the ProjectedCashFlows table.
Unfortunately this query is not doing that - it is only returning Customer and Facilities information when the Facility exists in the ProjectedCashFlows table.
I have used a MonthCalender table to list out each month in the year.
The relevant table information is:
Customers
CustomerCode
CustomerName
PrimaryArmId
Facilities
CustomerCode
FacilityId
FacilityCurrencyId
FaciliyLimit
FacilityDescription
ProjectedCashFlows
CustomerCode
FacilityId
ExpectedYear
ExpectedMonth
ExpectedAmount
ProjectedCashFlowStatusId
MonthsCalendar
ExpectedMonth
ExpectedYear
As an example I have a customer that has 4 rows in the Facilities table however, 2 of these facilities do not appear in the ProjectedCashFlows table so they are not being displayed.
If an entry doesn't exist in ProjectedCashFlows it should take the ExpectedMonth & ExpectedYear from the CalendarMonths table, return 0 for the ExpectedAmount and use the FacilityId from the Facilities table.
As you can probably work out I have just started to use LINQ.
Can anyone poke me in the right direction?
Your query uses p assuming it is non-null:
where d.ExpectedYear == currentYear
&& f.FacilityStatusId == 1
&& (p.ExpectedYear == null || d.ExpectedYear == p.ExpectedYear)
// etc
But you've used DefaultIfEmpty() which will logically create a sequence with a single null value when there are no ProjectedCashFlows.
So basically you need something like:
where d.ExpectedYear == currentYear
&& f.FacilityStatusId == 1
&& (p == null ||
((p.ExpectedYear == null || d.ExpectedYear == p.ExpectedYear)
// etc
))