LINQ - Sequence contains no elements - linq

I am using a LINQ query as below.
object.collection.where(t => t.id.Equals("2")).First();
I am getting the error "Sequence contains no elements". Why does the result throw an error when the result contains no elements? Should it not return null when no results are found? That is what happens when using SQL.

It's working as designed. The First() method is to be called when it's known at least one row will be returned. When this isn't the case, call FirstOrDefault().

object.collection.where(t => t.id.Equals("2")).FirstOrDefault();

Related

Asp.net Core 5.0 Linq Take(1).ElementAt(index)

I have a long Linq query and I'm trying to take one data in any index of that query.
My query is :
public IEnumerable<WebFairField> WebFairFieldForFair(Guid ID,int index)
{
return TradeTurkDBContext.WebFairField.Where(x => x.DataGuidID==ID)
.Include(x => x.Category)
.ThenInclude(x=>x.MainCategory).AsSplitQuery()
//
.Include(x=>x.FairSponsors)
.ThenInclude(x=>x.Company)
.ThenInclude(x=>x.FileRepos).AsSplitQuery()
//
.Include(x=>x.WebFairHalls.Take(1).ElementAt(index)) //Thats the point where i stuck*
.ThenInclude(x=>x.HallSeatingOrders)
.ThenInclude(x=>x.Company)
.ThenInclude(x=>x.FileRepos).AsSplitQuery()
//
.Include(x=>x.HallExpertComments).AsSplitQuery()
.Include(x=>x.Products).AsSplitQuery()
.Include(x=>x.FairSponsors).AsSplitQuery()
.AsNoTrackingWithIdentityResolution()
.ToList();
}
when I do that it gives me an error : Collection navigation access can be filtered by composing Where, OrderBy,ThenBy,Skip or Take operations.
I know I have to sort that data but I don't know how to do it. Can anyone show me how should I sort my data of that query ?
Thanks for any suggestion!!
The error
As you have mentioned, the line of
.Include(x=>x.WebFairHalls.Take(1).ElementAt(index)) //Thats the point where i stuck*
is causing the error. Basically you Take the first element and then try to call ElementAt. This is a problem technically, because you need to convert your collection to IEnumerable in order to be able to call ElementAt.
It is also a logical error, since if you take a single element, then it does not make sense to try and call ElementAt for it.
Skip
As Guru Strong pointed out, you can Skip, as Skip(index - 1).Take(1) which skips the first index - 1 elements and then takes the next one, which is the index'th element.
Sort
If you need to sort, call OrderBy. If you need several sorting criteria, then use ThenBy.

How to convert iqueryable<string> to string in linq?

i have the following code snippet.
in which i just want to return PartyName as a string.
but i get the error:"Cannot implicity convert type 'System.Linq.Iqueryable to string"
if i want to return only string then what to do?
please help me.
return objDatabase.FAPARs
.Where(f => (f.PARTY_CODE == "P003"))
.Select(f => f.PARTY_NAME);
An IQueryable<string> represents a query which could return any number of strings. You want one string - so you need to decide what to do in various situations:
What do you want to happen if the query has no results?
What do you want to happen if the query has one result? (I assume this is simple :)
What do you want to happen if the query has more than one result?
The set of methods which allow you to determine all of this are:
Single - fail if there isn't exactly one result
SingleOrDefault - fail if there's more than one result, return null if there are no results
First - fail if there are no results, return the first of many
FirstOrDefault - return null if there are no results, or the first of many
Last - fail if there are no results, return the last of many
LastOrDefault - return null if there are no results, or the last of many
In each case, "fail" means "throw an exception". (IIRC it's always InvalidOperationException, at least in LINQ to Objects, but I could be wrong.)
So if you're querying by an ID which must exist (i.e. it's a bug if it doesn't) then Single is probably appropriate. If you're querying by an ID which may not exist, then use SingleOrDefault and check whether the return value is null. If you're not querying by an ID, you probably want to use FirstOrDefault or just iterate over the results.
(Note that the default value being null is due to this being a query returning strings, and string being a reference type. In general it's the default value of the element type - so if you had an IQueryable<int>, the default returned would be 0.)
Try
return objDatabase.FAPARs .Where(f => (f.PARTY_CODE == "P003")) .Select(f => f.PARTY_NAME).SingleOrDefault();
Try this:
return objDatabase.FAPARs.Where(f => (f.PARTY_CODE == "P003")).Single(f => f.PARTY_NAME);
return objDatabase.FAPARs.FirstOrDefault(f => f.PARTY_CODE.Equals("P003")).PARTY_NAME
return objDatabase.FAPARs.OfType<FAPAR>()
.Where(f => (f.PARTY_CODE == PartyCode && f.COMP_NO == ComCode))
.Select(f => f.PARTY_NAME).SingleOrDefault();

no supported translation to SQL Help Linq -> SQL

I have a query that has a where clause that checks if the data element is contained within a list.
This query executes fine:
results = awardedStats.Where(r => guidReq.Contains(r.RequirementId) || orgAcr.Contains(r.Division))
.Select(r => r);
however this does not:
results = awardedStats.Where(r => guidReq.Contains(r.RequirementId) || orgAcrId.Contains(r.guidDivisionId))
.Select(r => r);
r.division is a string and orgAcr is a List
r.guidDivisionId is a Guid and orgAcrId is a List
I know that each list get the correct values, I can check the list in the debugger, but if I run the first query, everything runs through fine, if I run the second query I get an error stating that the member "guidDivisionId" has no supported translation to SQL
If orgAcrId is a List<Guid> and r.guidDivisionId is a uniqueidentifier column in SQL Server, this should be fine. Are you sure the column name isn't r.DivisionId?
Get all data from sql and call AsEnumarable() method on it and then apply the where. That way comparison would be done in memory and it won't complain about sql translation.
Another thing is that when you use contains, it's converted to Sql IN clause. All elements in the list are included in the IN clause. If your list has more than 2100 elements, then you would get sql exception saying that sql cannot accept more than 2100 parameters. Doing this kind of comparison in memory is safer.

In Linq, what's the difference between .FirstOrDefault and .SingleOrDefault

I don't know the difference between FirstOrDefault and SingleOrDefault. When should I use the first and when should I use the second?
FirstOrDefault() is for when zero or more results are expected to be present in the input collection and the call returns the first item if there are multiple results, Default if none.
SingleOrDefault() is for when zero or one result is expected in the input collection and the call returns the one result if exactly one result is present, Default if no results and exception if more than one result.
SingleOrDefault will throw a "Sequence contains more than one element" exception if more than one item exists.
firstordefault it will take number of rows but will just return first one of it if it is
null it can handle the exception
First it will take number of rows but will just return first one of it if it is
null it will throw the exception
singleordefault it will take only one row but will return it can handle exceptions if it is null
single it will take only one row but will return it & cannot handle exceptions
If your result set returns 0 records:
SingleOrDefault returns the default value for the type (e.g. default for int is 0)
FirstOrDefault returns the default value for the type
If you result set returns 1 record:
SingleOrDefault returns that record
FirstOrDefault returns that record
If your result set returns many records:
SingleOrDefault throws an exception
FirstOrDefault returns the first record
Conclusion:
If you want an exception to be thrown if the result set contains many records, use SingleOrDefault.
If you always want 1 record no matter what the result set contains, use FirstOrDefault

how to get second record in linq to sql

I have an exchange rate table. I need to get current rate and previous rate and then compare results.
I can get first record using FirstOrDefault.
When I am using ElementAtOrDefault, this error shows "The query operator 'ElementAtOrDefault' is not supported". How can I get the second record?
You can try this:
var query=data.Skip(1).Take(1);
Take() returns null if the element is not there (so is equivalent to FirstOrDefault()).
If you'd rather an exception was thrown (cos the second element is not there) like First() then use:
Skip(1).Single()
Try this simple implementation this might be useful
var query= (from p in db.Person where p.Person == person_id select p);
var firstResult = query.First();
var secondResult = query.Skip(1).Take(1).Single();
var thirdResult = query.Skip(2).Take(1).Single();
There's a detail not explicitly mentioned here: FirstOrDefault returns an Element, Skip(1).Take(1) returns a set of 1 element; i.e. the type returned by Skip(1).Take(1) is IEnumerable, while FirstOrDefault is not.
If you use
.Take(2)
you will get the first and second.
EDIT- If you need both the first and second, then the above will be more efficient than runing your query twice:
.Take(1)
.Skip(1).Take(1)
Collection.ElementAt(1)
will fetch the second record in the collection.
Select top 2, then select second element.
As John Anderson already pointed out Skip(1).Take(1) returns an IEnumerable of size 1.
In order to get the 2nd entry itself or else a null (i.e. no exceptions), I'm using the following:
var secondEntry = collection?.Skip(1)?.FirstOrDefault();
It may not work in your specific case, but may be useful for use cases of other.
Use .Skip(1) method

Resources