InvalidOperationException: Sequence contains more than one element - c#

I have the following code below for a payroll program.
The first dictionary holds the employee IDs and corresponding basic pays held in a master data table.
The second dictionary holds the employee IDs and corresponding basic pays held in a salary fitment table - used for processing.
I want to update the salary fitment basic pays for each employee ID that do not match in the master table. (Changes in salary).
var OHEMDictionary = employees.OrderBy(es => es.empID)
.ToDictionary(od => od.empID,
od => od.salary);
var SalaryFitmentDictionary = salaryFitments
.Where(x => x.U_PD_Code.Trim().ToString() == "SYS001")
.OrderBy(es => es.U_Employee_ID)
.ToDictionary(od => od.U_Employee_ID,
od => od.U_PD_Amount);
var difference = OHEMDictionary
.Where(kv => SalaryFitmentDictionary[kv.Key] != kv.Value);
difference.ToList().ForEach(x =>
{
decimal salary = x.Value.Value;
var codeToUpdate = salaryFitments
.Where(y => y.U_Employee_ID.Equals(x.Key))
.Select(z => z.Code)
.SingleOrDefault(); `**<---exception thrown here**`
var salaryFitment = salaryFitmentService
.GetSalaryFitment(codeToUpdate);
if (salaryFitment != null)
{
// Save record
salaryFitmentService
.UpdateSalaryFitment(salaryFitment, salary.ToString());
}
});
However, I keep getting the error 'Sequence contains more than one element'. How do I solve this error?

You can use FirstOrDefault() but SingleOrDefault throws an exception if more than one element exists.
Here you can see exactly what the single or default method does:
http://msdn.microsoft.com/en-us/library/system.linq.enumerable.singleordefault(v=vs.100).aspx

Related

C# - How to Order By in an ICollection?

I have an Applications table. An Application can have many ActivityPhases.
I use the following to display the latest ActivityPhase:
a.ApplicationActivityPhas.Where(aap => aap.ActivityPhas.WorkFlowStep == a.ApplicationActivityPhas.Max(x => x.ActivityPhas.WorkFlowStep)).Select(aap => aap.ActivityPhas.ActivityPhase)
Therefore, my Applications table only displays 1 ActivityPhase per Application record.
I have the following line that I am trying to use to order the ActivityPhase table column by:
data.OrderBy(a => a.ApplicationActivityPhas.FirstOrDefault().ActivityPhas.ActivityPhase);
The problem is that it is ordering the values within the ICollection. It does not order the values displayed in the Applications table.
First group by activity phase and select your maximum workflow step. Then select all the application phases that match this maximum workflow step.
a.ApplicationActivityPhas.GroupBy(aap => aap.ActivityPhase)
.Select(x => new { ActivityPhase = x.Key, MaxStep = x.Max(y => y.WorkFlowStep) })
.SelectMany(x => a.ApplicationActivityPhas.Where(y => y.WorkFlowStep == x.MaxStep && y.ActivityPhase == x.y.ActivityPhase))
The reason that my ordering was not working as expected is that the first ActivityPhase value was being used to determine the order, which was not always the correct one.
To grab the correct value, I just added the where clause that I use to display the correct value in my table:
data.OrderBy(a => a.ApplicationActivityPhas.Where(aap => aap.ActivityPhas.WorkFlowStep == a.ApplicationActivityPhas.Max(x => x.ActivityPhas.WorkFlowStep)).FirstOrDefault().ActivityPhas.ActivityPhase);

How to retrieve data from multiple tables using EF 5 linq method

I am facing a problem as discussed below.
I have four tables
PateintTable
PatientRecordTable(FK=PatientID)
RecordMedicineTable(FK=MedicineID,RecordID)
MedicineTable
I want to get a specific Patient data depending upon the PatientID of the patient along with the patient data, I want to obtain his medical-records (PatientRecordTable) plus medicines associated with each of his records.
I tried many tricks but exceptions occur when I try to get the medicines.
lstPrescribedMedicines.Items.Clear();
foreach (var item in result.RecordsMedicines)
{
lstPrescribedMedicines.Items.Add(item.Medicine.MedName);
}
I am implementing using(context=new mss-context()).
This is my query:
var pateintRecords = context
.PateintRecords
.Include(p => p.Patient)
.Include(m=>m.RecordsMedicines)
.Where(x => x.PatientID == pateintID).ToList();// as IQueryable;
When working with children of children, you have to include them:
var pateintRecords = context
.PateintRecords
.Include(p => p.Patient)
.Include(m=>m.RecordsMedicines)
.Include(m=>m.RecordsMedicines.Select(i => i.Items))
.Where(x => x.PatientID == pateintID).ToList();// as IQueryable;

The appropriate way to query List from different variable?

I have a table in which display many-to-many relationship. From the manager user, I will get a list of location that under manager management. Then from that list, I will get a list of user that related to those location. Here's my first implement to get location list
var locationManager = db.UserLocation.Where(x => x.userID == userID).ToList();
I don't know the appropriate to do the next step. Let's say manager's id is the userID with number 2. Therefor, the first line of code will return me with a list of UserLocation with userID = 2 which contain total of two locations with id of 1 and 2.
Database table Image
In my mind, the next line of code to print out UserLocation would be like this but I don't want to hard code number 1 or 2.
var locationRelated = db.UserLocation.Where(x => x.locationId == 1 || x.locationId == 2).ToList();
You can use Enumerable.Contains to filter with collection:
var locationIds = new []{1, 2};// get ids somehow
var locationRelated = db.UserLocation
.Where(x => locationIds.Contains(x.locationId))
.ToList();
But it seems that there is typo, case you are querying db.UserLocation again. If you want to get Location(assume it is called like that), you can do that in one query, if your relations in enities are set up correctly:
db.UserLocation
.Where(x => x.userID == userID)
.Select(x => x.Location)
.ToList();

Finding in a list that contains an attribute of an object

I'm trying to find which items in my list fill a certain criteria.
I have a List<Employee>, and each Employee has a List<Role> attribute. Each Role has an ID as an attribute. I'm trying to find all Employees that have a certain Role ID in the list. Here is my non-working sample:
var query = EmployeeList.Where(employee=> employee.Roles.Contains(role => role.ID == roleID)).ToList();
Use Enumerable.Any
var query = EmployeeList.Where(employee => employee.Roles
.Any(role => role.Id == roleID))
.ToList();
You can just change your Contains to Any (as you're just checking whether any of the roles of the employee matches your condition):
var query = EmployeeList.Where(employee => employee.Roles
.Any(role => role.ID == roleID))
.ToList();
Note that this won't be a terribly efficient approach - every employee has to be checked, and every role of every employee. If you need to do this often with the same set of employees but different role IDs, you could build a lookup from role ID to employees:
var lookup = EmployeeList.SelectMany(e => e.Roles,
(e, r) => new { Employee = e, Role = e })
.ToLookup(pair => pair.Role.ID,
pair => pair.Employee);
You can then just use:
foreach (var employee in lookup[roleID])
{
....
}

LINQ-To-SQL row number greater than

If i have an object of type Photo and a Result set which is sorted in a particular order, is there a way for me to get the position of the current Photo object in the result set. and then get all objects that would follow it?
You can do something like this (not terribly efficient):
var result =
photos.Select((p, i) => new { Index = i, Photo = p })
.SkipWhile(x => x.Photo != photo).Skip(1);
This will give you all photos following photo combined with their index in the original collection.
If you're sorting against an Id:
// gets the previous photo, or null if none:
var previousPhoto = db.Photos
.Where(p => p.Id < currentPhotoId)
.OrderByDescending(p => p.Id)
.FirstOrDefault();
// gets the next photo, or null if none:
var nextPhoto = db.Photos
.Where(p => p.Id > currentPhotoId)
.OrderBy(p => p.Id)
.FirstOrDefault();
If you have custom ordering, you'd need to replace the OrderBy/OrderByDescending expression with your custom ordering. You'd also need to use the same ordering criteria in Where() to get only those photos before or after the current photo.
Not sure if I understand correctly but this might help:
var result = photos.Skip(100); // 100 would be the position of current object.
// if you don't know the index of the current object:
// This won't work on LINQ to SQL directly, do it on a list or something.
var result = photos.SkipWhile(x => x != currentObject).Skip(1);
In reality, if you are dealing with a database, there should be some identifier (a set of columns) you are sorting by. If you want to do the whole thing on the server side, you can grab the properties of the current object and filter the result set specifically for objects that would come after that in the sort order you want.
Index of the photo:
result.IndexOf(photo);
Items after it:
result.SkipWhile((q, i) => i <= result.IndexOf(photo));

Categories