NullReferenceException in LINQ Query - c#

I am getting an unusual "NullReferenceException was unhandled by user code" error in this LINQ query:
List<UDIDInfo> d2Android = d2.Where(x.DeviceOS == (byte)DeviceOS.Android).ToList();
I went ahead and added a null check and am still getting the error
List<UDIDInfo> d2Android = d2.Where(x => x.DeviceOS != null && x.DeviceOS == (byte)DeviceOS.Android).ToList();
Note that (byte)DeviceOS.Android and d2 are both not null
Edit (Solution):
List<UDIDInfo> d2Android = d2.Where(x => x != null && x.DeviceOS != null && x.DeviceOS == (byte)DeviceOS.Android).ToList();

What if x is null? That is, the enumerable d2 contains a null item.
Try the following. You shouldn't get any null reference exception.
List<UDIDInfo> d2Android = d2
.Where(x => x != null)
.Where(x => x.DeviceOS != null)
.Where(x => x.DeviceOS == (byte)DeviceOS.Android)
.ToList();

avoid the argument null exception in LINQ like below
Summaries = (from r in Summaries
where r.Contains(SearchTerm)
orderby r
select r).ToArray();
In this case, if null passed to searchTerm you can check the null expression like below
Summaries = (from r in Summaries
where string.IsNullOrEmpty(SearchTerm) ||r.Contains(SearchTerm)
orderby r
select r).ToArray();

Related

how to debug `Null reference exception occured` in linq?

string search = textBoxNachname.Text;
var Liste = _db.T_Subscribers
.Where(x => x.firstname.StartsWith(search))
.Except(_selectedcourse.T_Coursedetail.Select(b => b.T_Subscribers))
.Where(M => M.T_Tln_Student == null || M.T_Tln_Stud.Status.T_Status.T_Statusart == _studentEx).ToList();
I have written the above piece of code to extract a list whose name starts with the Search element in textbox...then I need to exclude the names who have already enrolled for the course, then if they are not the students of the Institution (M => M.T_Tln_Student == null) and ex-students include in the list..
But I am getting Null reference exception occurred...
This is how you can debug this:
var Liste1 = _db.T_Subscribers.Where(x => x.firstname.StartsWith(search));
var Liste2 = Liste1.Except(
_selectedcourse.T_Coursedetail.Select(b => b.T_Subscribers));
var Liste3 = Liste2.Where(M =>
M.T_Tln_Student == null ||
M.T_Tln_Stud.Status.T_Status.T_Statusart == _studentEx);
var Liste = Liste3.ToList();
The focus is to use this technique to split things.
look at this line:
.Where(M => M.T_Tln_Student == null ||
M.T_Tln_Stud // might be null
.Status // might be null
.T_Status // might be null
.T_Statusart // might be null
== _studentEx)
I would suggest that you start your search for the NullReferenceException here
.Where(M => M.T_Tln_Student == null ||
M.T_Tln_Stud == null ||
M.T_Tln_Stud.Status == null||
M.T_Tln_Stud.Status.T_Status == null ||
M.T_Tln_Stud.Status.T_Status.T_Statusart == null ||
M.T_Tln_Stud.Status.T_Status.T_Statusart == _studentEx)

Trying to order LINQ results

To one of my tables I added a sortOrder. I now need to update this query to respect the sortOrder authority!
Here is my current query:
var HTMLdocs = db.ProcedureDocs.Where(m => m.Procedures.Processes.processID == id && m.Document.html != null && m.Document.approvedBy != null).Select(m => m.Document);
The table that has sortOrder is Procedures.
How can I get the above query to return results that are ordered by sortOrder.
Here is the table structure.
Processes can have 0 or many Procedures.
Document can have 0 or many ProcedureDocs.
ProcedureDocs has a foreign key to Procedures on procedureid.
I somehow need to grab a collection of Document that somehow respects the order found in the Procedures table.
Let me know if you need any other information.
Try something like this:
var HTMLdocs = db.ProcedureDocs
.Where(m => m.Procedures.Processes.processID == id &&
m.Document.html != null &&
m.Document.approvedBy != null)
.OrderBy(m => m.Procedures.sortOrder)
.Select(m => m.Document);
Or in query syntax:
var HTMLdocs =
from m in db.ProcedureDocs
where m.Procedures.Processes.processID == id &&
m.Document.html != null &&
m.Document.approvedBy != null
orderby m.Procedures.sortOrder
select m.Document;
var HTMLdocs = db.ProcedureDocs
.Where(m => m.Procedures.Processes.processID == id
&& m.Document.html != null && m.Document.approvedBy != null)
.OrderBy(x=>x.Procedures.sortOrder)
.Select(m => m.Document)

Linq query for distinct data from a table with where condition

I have an sql statement like this:
select distinct(agent_name)
from properties
where agent_name not in ('null','')
I want the linq query in C# page
Assuming you're comparing to the string value 'null' like your original query:
List<string> agentNames = db.Properties.Where(p=>p.AgentName != "null" &&
p.AgentName != "")
.Select(p => p.AgentName)
.Distinct()
.ToList();
If you're actually comparing to a null value just change it to:
List<string> agentNames = db.Properties.Where(p=>p.AgentName != null &&
p.AgentName != "")
.Select(p => p.AgentName)
.Distinct()
.ToList();
var result = context.Properties.Where(p => p.AgentName != null
&& p.AgentName != "")
.GroupBy(p => p.AgentName)
.Select(g => g.Key);
Try something like this
var result = (from dbo in database.Table
where dbo.agent_name!=null and dbo.agent_name !=''
select dbo.agent_name).Distinct();
or if you have a list already
var result = (list.Where(a => a.agent_name!=null && a.agent_name!='').Select(
a.agent_name)).Distinct();
You can use it like this
var forms = db.properties.
Where(a => a.agent_name == 'null' || a.agent_name == null).
Select(x => x.agent_name).
Distinct().
ToList();
Its equivalent SQL statement, which is designed by LINQ to SQL is
SELECT
[Distinct1].[agent_name] AS [agent_name]
FROM ( SELECT DISTINCT
[Extent1].[agent_name] AS [agent_name]
FROM [dbo].[properties] AS [Extent1]
WHERE [Extent1].[agent_name] = N'null' OR [Extent1].[agent_name] = N''
) AS [Distinct1]

Entity Framework: Unable to create a constant value of type 'System.Collections.Generic.IList`1'

This has caused me no end of problems today. I have this simple query
var result =
DataContext.Accommodations.Where(a =>
(criteria.MinPrice == null || a.AccommodationRates.Any(r => r.From >= criteria.MinPrice)) &&
(criteria.MaxPrice == null || a.AccommodationRates.Any(r => r.To <= criteria.MaxPrice)) &&
(criteria.Locations == null || criteria.Locations.Count == 0 || a.AccommodationPlaceJoins.Any(j => criteria.Locations.Contains(j.Place.PlaceName)))
);
The last line of this query is causing me problems
(criteria.Locations == null ||
criteria.Locations.Count == 0 ||
a.AccommodationPlaceJoins.Any(j => criteria.Locations.Contains(j.Place.PlaceName)))
The error it gives is
Unable to create a constant value of type
'System.Collections.Generic.IList`1'. Only primitive types ('such as
Int32, String, and Guid') are supported in this context.
I'm not even trying to create a list. All I'm trying to do here is bring back accommodations which are associated to a place (where the place name in the Place table which is linked to the Accommodation table via the AccommodationPlaceJoin table) is equal to any one of the place names in criteria.Locations (which is of type IList).
I've tried changing this line to this, but it didn't work.
(criteria.Locations == null ||
criteria.Locations.Count == 0 ||
a.AccommodationPlaceJoins.Any(j => criteria.Locations.Any(l => l == j.Place.PlaceName)))
The constant value EF can't create is null for the comparison criteria.Locations == null. You need to split the query into two cases and do the check for the empty list outside of the query, for example like so:
var result = DataContext.Accommodations.Where(a =>
(criteria.MinPrice == null ||
a.AccommodationRates.Any(r => r.From >= criteria.MinPrice)) &&
(criteria.MaxPrice == null ||
a.AccommodationRates.Any(r => r.To <= criteria.MaxPrice)));
if (criteria.Locations != null && criteria.Locations.Count > 0)
{
result = result.Where(a => a.AccommodationPlaceJoins
.Any(j => criteria.Locations.Contains(j.Place.PlaceName)));
}
Edit
BTW: Composing the whole query would make it better readable in my opinion and will simplify the SQL that has to be sent to the database:
IQueryable<Accommodation> result = DataContext.Accommodations;
if (criteria.MinPrice != null)
result = result.Where(a => a.AccommodationRates
.Any(r => r.From >= criteria.MinPrice));
if (criteria.MaxPrice != null)
result = result.Where(a => a.AccommodationRates
.Any(r => r.To <= criteria.MaxPrice));
if (criteria.Locations != null && criteria.Locations.Count > 0)
result = result.Where(a => a.AccommodationPlaceJoins
.Any(j => criteria.Locations.Contains(j.Place.PlaceName)));
I had this same issue when trying to pass a list of strings for comparison into an EF core query recently and found that it resolves the issue to assign an empty array or empty list to the value in case it is null rather than doing the null check right in the EF Core query.
This allows you to query the EF Core database without the null error and you don't need a bunch of conditional branching for separate queries - just one query with a bit of null coalescence.
So your code fixed this way would look like this:
var locations = criteria.Locations == null ? new List<Location>() : criteria.Locations;
var result =
DataContext.Accommodations.Where(a =>
(criteria.MinPrice == null || a.AccommodationRates.Any(r => r.From >= criteria.MinPrice)) &&
(criteria.MaxPrice == null || a.AccommodationRates.Any(r => r.To <= criteria.MaxPrice)) &&
(locations.Any() ? a.AccommodationPlaceJoins.Any(j => criteria.Locations.Contains(j.Place.PlaceName))) : true);
Keep in mind I am not sure of the type for locations or accomodationplacejoins so I cannot be sure the above code will exactly work but the general idea is we are doing a .Any() instead of checking for null. This way we can keep our query a little simpler. We are then using a ternary expression within the last block of our where clause so if the locations list turns out to be empty, we skip the condition entirely and just return true which coalesces the empty list if it is empty.

How to ignore 'where' and 'order by' condition if the column is null in LINQ

I have list of transaction objects and want to order them by certain condition depending on view user is currently on.
The problem I have is that in order to add a condition in a where clause, first I need to check if it is null or not to prevent null pointer exception. This causes records with the column null being filtered out(and I want to include them at bottom of the list).
How can I modify the query so that it ignores the conditions(where and order by) if that column is null and still append them to the result set?
This is one example query:
transactions = transactions
.Where(t => t.PurchaseRequisition != null &&
t.Award != null && t.PurchaseRequisition.RequisitionedBy != null)
.OrderBy(t => t.Award.ContractNumber).
ThenBy(t => ToSafeString(t.Award.ContractNumber)).
ThenBy(t => ToSafeString(t.PurchaseRequisition.RequisitionedBy.FullName));
public string ToSafeString(string s)
{
return s ?? String.Empty;
}
// I want records where PurchaseRequisition or Award is null to be appended to the result set.
You simply need to modify your OrderBy and ThenBy clauses:
.OrderBy(t => t.Award == null || t.Award.ContractNumber == null)
.ThenBy(t => t.Award == null ? "" : ToSafeString(t.Award.ContractNumber))
.ThenBy(t => t.PurchaseRequisition == null ? ""
: ToSafeString(t.PurchaseRequisition.RequisitionedBy.FullName));
Now you can completely remove the Where clause.

Categories

Resources