LINQ Query Issue, Sequence contains no elements - c#

I'm trying to update a single record in a table, but when I run .Firstordefault(), I get the error: "Object reference not set to an instance of an object.", and if use it with .First(), I get "Sequence contains no elements".
Using it another place, its working fine, but this time its causing errors.
Here's the code:
public class AllownceDetails
{
public int ta_id{get;set;}
public int tvrid{get;set;}
public DateTime ofDate{get;set;}
public string status{get;set;}
public string userid {get;set;}
}
//Update Method
public void Update(AllownceDetails Allowncedtl)
{
var ta = (from a in ce.tbl_tvrallownce
where a.tvrid == Allowncedtl.tvrid
//error: Sequence contains no elements
select a).SingleOrDefault();
ta.status = Allowncedtl.status;
//error:Object reference not set to an instance of an object
ce.SaveChanges();
}

The query must not be returning any data. Run a profiler on the SQL database to see the physical query being executed and try to execute it manually against the database to see what the data looks like. You probably have to adjust the query (or the data) to get the results you're looking for.
"Sequence contains no elements" is basically LINQ's way of telling you that you're trying to reference an element from a list that doesn't have anything. So calls to things like .First() or .Single() can't find anything, hence the error.
When you change the calls to something like .FirstOrDefault() or .SingleOrDefault() then it will go with "default" value for that type, and for reference types the default is null. So if you set something to null and then try to call a method on it, you'll get object reference not set to an instance of an object.

The Single method throws this exception when there are no elements in list(query) or there are multiple elements.
The SingleOrDefault method throws an exception when there are multiple elements in the list. Returns null when there are no elements.
The FirstOrDefault method return the first item in the list or null. There are no exceptions.
Use it and the check the reference for null
if (ta != null )
{
ta.status = Allowncedtl.status;
ce.SaveChanges()
}
The source will always be an object, so no worries about it in your case.

All that means is that your query isn't matching anything. Presumably Allowncedtl.tvrid is an ID which doesn't match anything in the database. You shouldn't assume that SingleOrDefault will return a non-null value. Only use SingleOrDefault when you're expecting that there may be no values - and cope with that. If a failure to find a value indicates a bug, you should use Single (or perhaps First) instead.
We can't tell anything about what the underlying cause of your error is - you should log which ID you were looking for, work out why you were looking for that, and then check it in the database.

Related

Point variable to specific element of observable collection

I'd like to set a variable of type "ReturnOrderDetailLine" to be a specific "ReturnOrderDetailLine" within an "Observable Collection" of "ReturnOrderDetailLine"s.
Identifying the element I am interested in is done via searching for a barcode
public ObservableCollection<ReturnOrderDetailLine> ReturnLines
{
get => returnLines;
set
{
returnLines = value;
OnPropertyChanged(nameof(ReturnLines));
}
}
public ReturnOrderDetailLine SelectedLine { get; set; }
protected override void UpdateBarcodePickedOrReturnedQty(string barcodeText)
{
var returnDetailLine = (ReturnOrderDetailLine)ReturnLines.Where(s => s.Barcode.Equals(barcodeText));
SelectedLine = returnDetailLine;
OnPlusCommand();
}
I have tried using search methods like .select() or .where() but it seems the output of these functions are the same.
I've tried casting the result of .where() to the type I want but I receive a "Specified cast is not valid" error.
I've trawled googled for about an hour now and have gotten no insights.
Anyone have any ideas?
There are multiple methods that might satisfy your needs:
FirstOrDefault(): returns a first item of potentially multiple (or default if none exists).
First(): returns a first item of potentially multiple (or throw an exception if none exists).
SingleOrDefault(): assumes that there is a single item and returns it (or default if none exists). Multiple items are a violation of contract, an exception is thrown.
Single(): assumes that there is a single item and returns it (or throw an exception if none exists). Multiple items are a violation of contract, an exception is thrown.
Here's an example of using the FirstOrDefault() method in your scenario:
ReturnOrderDetailLine item = ReturnLines.FirstOrDefault(s => s.Barcode.Equals(barcodeText));
More about the differences between the FirstOrDefault(), First(), SingleOrDefault() and Single() can be found in this helpful stackoverflow answer.

Object property suddenly becomes null when queried with a linq statement

I have the following linq query:
private List<Port> DoCountriesSearch(string search)
{
return Countries.Where(x => x.CountrySearch.ToLower().Contains(search.ToLower())).ToList();
}
I have an object called Countries which is a list of Port objects with various properties. Each Port object contains a property called CountrySearch which you can see here:
But as soon as I try to run the linq query on Countries, suddenly the CountrySearch property is null which throws a null reference exception:
I've never had this issue with linq before. What am I missing?
Your list has a lot of entries. In some entries CountrySearch is not null, in others it is null. There is no magic happening with LINQ here.
You can fix this with a Null-conditional operator
private List<Port> DoCountriesSearch(string search)
{
return Countries.Where(
x => x.CountrySearch?.Contains(
search,
StringComparions.CurrentCultureIgnoreCase) == true
).ToList();
}
Note that == true is required here because we have to cope with null values.
See also:
Best way to check for nullable bool in a condition expression.
StringComparison Enum for possible values.
The issue was entirely my fault. I had a buried method that was appending Port objects to the bottom of the list that did not come from the database, therefore the CountrySearch fields for those items were indeed null.

What is the logical difference between using Single and SingleOrDefault? [duplicate]

This question already has answers here:
Should I use Single() or SingleOrDefault() if there is a chance that the element won't be found?
(9 answers)
Closed 5 years ago.
I am not sure where shall I use Single and where shall I use SingleOrDefault. I understood the definition for both.
Single:
It will always return one row.
If no row found I will get an exception.
If multiple rows found I will get an exception.
SingleOrDefault:
It will always return one row, if not found then default value is returned (What is the meaning of this DEFAULT VALUE").
If multiple rows then exception.
Question 1: What is the meaning of "It will return default value"
Question 2: When to use Single and when to use SingleOrDefault.
I have a delete function where I have below code:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Delete(int resumeId)
{
var r = _context
.Resumes
.Where(c => c.ResumeId == resumeId).SingleOrDefault();
_context.Resumes.Remove(r);
_context.SaveChanges();
return RedirectToAction("ResumeCenter");
}
I just blindly put SingleOrDefault everywhere (where I ATMOST expect one value), Please tell me a real world scenario when I should use "Single" and where I should use "SingleOrDefault".
As you said -
Single() will raise an exception if no row found.
SingleOrDefault() will instead return the default value (null for reference types, 0 for ints, \0 for chars etc`).
Use Single() in one of two cases:
When not getting a row is something that should not happen, and if it does, it means something is wrong.
When you are dealing with value types (ints, chars, etc'), and the default value might be a valid value in your values system (for instance, if you are getting 0 for an int but can't tell if it's because you got no row back or it's a valid value.
Use SingleOrDefault() for any other case.
If the row is not found, you'll need to compare the value you get to it's default value.
For further reading, here is a link to Microsoft page on the default value expression.
It's almost (but not quite) a question of style. Which do you prefer?
Single:
try
{
var x = someEnumerable.Single();
}
catch (InvalidOperationException)
{
//Did not contain exactly one record
}
SingleOrDefault:
var y = someEnumerable.SingleOrDefault();
if (y == null)
{
//Did not contain exactly one record
}
The exception-based approach is a little more coding, but it is nice because exceptions can be allowed to bubble up. That being said, I usually use the XXXOrDefault variants to avoid stack unwind, which can be poor for performance. As a rule you should avoid throwing exceptions when behaviors are expected.
P.S. The "default" for any type can be obtained by using the keyword default(type). For integers it is zero, for dates it is MinValue, for reference types it is null, etc.
P.P.S. In your example I would use Single and allow an exception to be thrown if the row is missing or there is more than one. Otherwise you may end up passing null to the subsequent Remove method. While that would fail too, it'd fail a line later than it ought to, resulting in a deceptive stack trace and making troubleshooting a little trickier.
OTOH, with small changes, you could make either one work:
public ActionResult Delete(int resumeId)
{
var r = _context
.Resumes
.Where(c => c.ResumeId == resumeId).SingleOrDefault();
if (r == null)
{
return RedirectToAction("ErrorPage");
}
else
{
_context.Resumes.Remove(r);
_context.SaveChanges();
return RedirectToAction("ResumeCenter");
}
}
Or
public ActionResult Delete(int resumeId)
{
var r = _context
.Resumes
.Where(c => c.ResumeId == resumeId).Single(); //Error will bounce up to Application_Error or other global handler
_context.Resumes.Remove(r);
_context.SaveChanges();
return RedirectToAction("ResumeCenter");
}
as the function name suggest you when you say
list.single();
then that means
"I want the single record from the list" and hence you get the single
record (the 1st one)"
and when yo say
list.SingleOrDefault();
then that means
"I wan the single record and if the record dosen't exist the i would
like to have the default value of the object"
its your approch completely you can also go for
FirstOrDefault();
just like single or default
Single :
It returns a single specific element from a collection of elements if element match found. An exception is thrown, if none or more than one match found for that element in the collection.
SingleOrDefault:
It returns a single specific element from a collection of elements if element match found. An exception is thrown, if more than one match found for that element in the collection. A default value is returned, if no match is found for that element in the collection.
When you know that there has to be a value for some thing in the database, use Single() because you would want to get an exception if the "very expected value" in the database does not exist. Data like EmployeeName for a particular employee code.
Use SingleOrDefault() when you know employee is a temporary employee and his department may not show up in the main database. But if value for department exists, it should be only one value. He will not be working for multiple departments at once.
http://www.c-sharpcorner.com/blogs/singleordefault-vs-firstordefault-in-linq-query1
Single() - Atleast one value is expected in data store, and you would want it. You want to know if there is no value or multiple values. In that case, you get an exception and check.
SingleOrDefault() - Give one record with the default value if it does not exist. It does not matter whether on not anything is available for the record. But it should not be multiple records.

Benefits between .ToList().First() verse .Single for IQueryable in c#

So I am running a linq query on a NOSQL database that should return only a single object if one exists with that Id or nothing if nothing exists, but it is possible there are two objects with the same id in the database (if someone else messed up.) Currently I have it implemented as follows:
(from c in [IQueryableThing] where c.Id.Equals(id)).ToList().First()
I have also considered the alternative
(from c in [IQueryableThing] where c.Id.Equals(id)).Single()
I assume .Single() is faster but I am concerned that neither of these handles the case that there is no object with the correct id in the database. I don't care if there is more than one returned. I only want one of them. Eventually I will implement something to return the most recently modified.
Basically my question is what is the best way to solve this problem of converting a queryable to a single instance in a way that handles the cases where there is no object with the correct id and there is more than one object with the correct id.
It sounds like you just want to call FirstOrDefault(), which does exactly what the name implies.
Default means null.
You should not call ToList(); that will needlessly download all of the results from the database.
Using IQueryable.Single is more efficient:
Calling ToList enumerates the entire result set and stores each item in an single, contiguous array in memory. The First then just takes the first item from the array.
Calling IQueryable.Single evaluates only the first item in the list, and if no items are returned, throws an exception. It then checks to see if there are any more items in the result set, and throws an exception if there are any.
If you'd like to handle the case where no items exist in the set which match your criteria, but don't care if there are more than one, I'd strongly recommend using FirstOrDefault instead:
var result = (from c in [IQueryableThing] where c.Id.Equals(id)).FirstOrDefault();
if (result == null)
{
// no items found
}
This will translate to a TOP 1 in SQL, and simply return the first item in the result set, or if the result set is empty, it will simply return null (or the default value if you're dealing with structs).
The .ToList() shouldn't make a difference, it will just enumerate the queryable into an in-memory list. For your situation, you have a number of options. The two you've shown behave very differently:
.First() - This will return the first element in the enumeration, or throw an exception if there are none.
.Single() - This will return the only element in the enumeration, or throw an exception if there are none or if there are more than one.
.FirstOrDefault() - This will return the first element in the enumeration, or a default value (which is null for reference types) if there are none.
.SingleOrDefault() - This will return the only element in the enumeration, or a default value (which is null for reference types) if there are none, or throw an exception if there are more than one.
It sounds like you want to use .FirstOrDefault(). Check if the result is null. If it is, there were no matching elements. If it isn't, you have the first matching element.
I believe you are looking for Enumerable.FirstOrDefault
Returns the first element of a sequence, or a default value if the
sequence contains no elements.
You should use .FirstOrDefault(c => c.ID.Equals(id));
It will return default if nothing is found (default is null for classes) or the first one it finds.
In case you are sure that ONE and only ONE item exists and you will want to use Single()
If case you are not sure how many items will be returned used First() Or FirstOrDefault().
The difference is that Single() will throw an exception if more than one item exists. Very usefull if you want to trap insertion errors etc on a database without unique constraints.

How check null value for a proxy

I have a generic methode for load the entity. I need to check result value for null value.
public TEntity LoadById(long id)
{
TEntity result = SessionInstance.Load<TEntity>(id);
if (result != null) //This condition is always true
if (result.Id == 0 ) //Throws ObjectNotFoundException
throw new Exception("Ex Text");
return result;
}
But my condition ( if (result != null) ) is always true and next line result.Propagate() is throw ObjectNotFoundException exception by this message : No row with the given identifier exists[RCISP.Domain.Entities.Person#1000]
Because result entity is a proxy.
How can I check a condition for null value in a proxy?
Use NHibernate's ISession.Get instead of ISession.Load. Load throws an exception if the requested item does not exist, but it might also return a proxy that is later used to load the object from the database - and will only then throw if the item does not exist. That's what is happening to you.
Get on the other side returns null if the item does not exist in database. Exactly what you want.
More on that topic here.
Daniel's initial answer is correct. According to Ayende's blog, Load should only be used when you know that the item exists in the database.
Load will never return null. It will always return an entity or throw an exception. Because that is the contract that we have we it, it is permissible for Load to not hit the database when you call it, it is free to return a proxy instead.
Why is this useful? Well, if you know that the value exist in the database, and you don’t want to pay the extra select to have that, but you want to get that value so we can add that reference to an object, you can use Load to do so
In your example, the ObjectNotFoundException can only occur when the item does not exist in the database. If you can't guarantee that the item is present, you need to use Get not Load.

Categories

Resources