How to ignore 'null' in order by clause - linq

How i can ignore Null in name property when orderby
student.Students= student.student.OrderBy(s=> s.Name ?? null).ToList();
The above code always return list of students having Name = null as 1st element in the list and student with name 'system' in the end.
What i want to ignore/exclude null in orderby. the null should always come to end of the the list

You can make a conditional OrderBy:
student.Students= student.student
.OrderBy(s=> s.Name == null ? 1 : 0)
.ThenBy(s => s.Name)
.ToList();
This splits first into two groups, the items with s.Name != null and those with s.Name == null. The second sort-condition is the Name itself.

Related

How to compare IEnumerable<string> for null in Linq query

For the following query:
var result = from sch in schemeDashboard
join exp in Expenditure on sch.schemeId equals exp.SchemeCode
into SchExpGroup
where sch.SectorDepartmentId == selectedDepartmentId &&
sch.YearCode == StateManager.CurrentYear
orderby sch.ADPId
select new
{
ModifiedAmounts = SchExpGroup.Select(a => a.ModifiedAmounts),
ProjectName = sch.schemeName,
ADPNo = sch.ADPId,
Allocation = sch.CurrentAllocation,
Expenditures = from expend in SchExpGroup
where expend.YearCode == StateManager.CurrentYear &&
expend.DepartmentId == selectedDepartmentId &&
InvStatus.Contains(expend.Status)
orderby expend.ADPId
group expend by expend.InvoiceId
};
I want to filter the above query on a condition so that result gives only those records where "ModifiedAmounts" are not null. I have tried as follow:
if (rbList2.SelectedIndex == 6)
{
result = result.Where(a => a.ModifiedAmounts != null));
}
but this gives error as:
Cannot compare elements of type
'System.Collections.Generic.IEnumerable`1'. Only primitive types,
enumeration types and entity types are supported.
Any suggestions as I am lost as how to rephrase the filtered query.
I think the problem is that ModifiedAmounts will never be null. Select will return an empty list. Unless SchExpGroup is null in which case you will get a null reference exception.
Try changing your code to
result = result.Where(a => a.ModifiedAmounts.Any());
if (rbList2.SelectedIndex == 6)
{
result = result.Where(a => a.!ModifiedAmounts.Any());
}

LINQ query with Left Join, Group by without null List

I am working on LINQ query with Left-Join and groupBy, so I have list of questions which may or may not have answer collections. I want all the question group by question and their answer list, if it is null then don't want to add.
My current solution works fine but it still add a list with null where no answer is there hence giving me wrong result on Answer count()
var dhd = (from question in Context.Questions
join answer in Context.Answers on question.Id equals answer.QuestionId into ps
from answerDetail in ps.DefaultIfEmpty()
group answerDetail by question into grouped
select new
{
Question = grouped.Key,
Answer = grouped.ToList(),
//Answer = grouped.ToList() == null ? "(No Answer)" : grouped.Select(x => x.Value).FirstOrDefault(),
TotalAnswerCount = grouped.Count()
}).ToList();
I have tried following script in above code and it throw null exception
Answer = grouped.ToList() == null ? "(No Answer)" : grouped.Select(x => x.Value).FirstOrDefault(),
When you call ps.DefaultIfEmpty() it's making a list with null for non-matching element. If you want to get just null instead of a list with a null element, then try this code:
Answer = grouped.FirstOrDefault() == null ? null : grouped.ToList(),
If there's no match, then Answer is null, otherwise you get a list.
I think issue occur because of type so try this one:
Answer = grouped.ToList() == null ? null : grouped.Select(x => x.Value).FirstOrDefault(),

LINQ Query - Get the next row with matching parameters

I've got a database table with the following schema:
id
screenshot
language
projects_ID
I'm need to write a LINQ query, that, given an 'id', 'projects_ID', and 'language', will return the 'id' of the next row that has a matching 'projects_ID' and 'language'.
In English, my query would be:
select the next 'id' from screenshots after the current 'id' where
'projects_ID' == current 'projects_ID' and language == current 'language'
Is this possible to do this via LINQ?
Thanks.
Sounds like you probably want:
var next = table.Where(item => item.id > lastId &&
item.projects_ID == projects_ID &&
item.language == language)
.OrderBy(item => item.id)
.FirstOrDefault();
Or as a query expression:
var next = (from item in table
where item.id > lastId &&
item.projects_ID == projects_ID &&
item.language == language
orderby item.id
select item).FirstOrDefault();
The result will be null if there are no matches (e.g. if you're already looking at the last ID). This is assuming by "next" you mean "matching item with the lowest ID greater than the current one".

Can't enumerate LinQ results with left join

var itemSet = from item in da.GetList<Models.account>()
join file in objFileStorageList
on item.account_id equals file.parent_id into objFile
from fileItem in objFile.DefaultIfEmpty()
where item.company != null && item.company.company_id == 123
orderby item.updatedDate descending
select
new
{
Id = item.account_id,
RefNo = item.refNo,
StartDate = item.StartDate ,
EndDate = item.EndDate ,
Comment = item.comment,
FileStorageID = fileItem != null ? fileItem.fileStorage_id : -1,
Identification = fileItem != null ? fileItem.identifier : null,
fileName = fileItem != null ? fileItem.file_nm : null
};
It raises error message when I try to enumerate through collection result from Linq query above.
LINQ to Entities does not recognize
the method
'System.Collections.Generic.IEnumerable1[SCEFramework.Models.fileStorage]
DefaultIfEmpty[fileStorage](System.Collections.Generic.IEnumerable1[SCEFramework.Models.fileStorage])'
method, and this method cannot be
translated into a store expression
foreach (var item in itemSet)
{
string itemRef= item.RefNo;
}
Please suggest me any solutions.
Thanks in advance.
I think the problem with this is the following 'from' clause:
from fileItem in objFile.DefaultIfEmpty()
Note that your LINQ query may only be executed at the time the result collection is executed. So while you think your exception is in the foreach, it's actually within your expression. This breaks because the possible null value of objFile.DefaultIfEmpty() cannot cast into an IEnumerable.
Try removing the DefaultIfEmpty call and see what happens.

linq subquery returning null

I have an odd linq subquery issue.
Given the following data structure:
Parents Children
------- --------
Id Id
ParentId
Location
HasFoo
(obviously this is not the real structure, but it's close enough for this example)
I'm able to run this query and get a desired result:
bool b = (from p in Parents
from c in Children
where p.Id == 1 && c.ParentId == p.Id && c.Location == "Home"
select c.HasFoo).SingleOrDefault();
So if there is a child that has the Location "Home" for a Parent of Id 1, I will get that Child's "HasFoo" value, otherwise, I'll get false, which is the "default" value for a bool.
However, if I try and write the query so I have a list of Parent objects, like so:
var parentList = from p in Parents
select new ParentObject
{
ParentId = p.ParentId,
HasHomeChildren = p.Children.Count(c => c.Location == "Home") > 0,
HasHomeChildrenWithFoo = (from c in p.Children where c.Location == "Home" select c.HasFoo).SingleOrDefault()
}
I get the following error when iterating over the list:
The null value cannot be assigned to a member with type System.Boolean which is a non-nullable value type.
I don't see where this "null" value is coming from, however.
I wonder if the compiler is inferring HasHomeChildrenWithFoo to be bool, but then actually casting to a nullable bool (thus messing up your SingleOrDefault call). At any rate, I'd be willing to bet you could fix it with a cast to a nullable type in that final select which you can then manually default to false when null. It'd probably make the error go away, but it's kind of a brute-force kludge.
var parentList = from p in Parents
select new ParentObject
{
ParentId = p.ParentId,
HasHomeChildren = p.Children.Any(c => c.Location == "Home"),
HasHomeChildrenWithFoo = (from c in p.Children where c.Location == "Home" select (bool?)c.HasFoo) ?? false)
}

Resources