This question already has answers here:
C# Linq intersect/except with one part of object
(7 answers)
Closed 3 years ago.
There are 2 large list of objects, where I need to do a where clause and find the matching records.
List<A> a= ...;
List<A> b = ...;
A model
Id
Name
Age
Address
I need to return a list that contains all the object of List after comparing with List.
The properties I should check is : If the Ids are equal, if the Names are equal and if the ages are equal.
List<A> common = a.Where(n => b.Select(o => o.Id).Contains(n.Id))
.Where(n => b.Select(o => o.Name).Contains(n.Name))
.Where(n => b.Select(o => o.Age).Contains(n.Age))
There should be something wrong with this, as it returns a Null.
You can create custom EqualityComparer:
public class ModelEqualityComparer : IEqualityComparer<Model>
{
public bool Equals(Model x, Model y)
{
return x.Id == y.Id && x.Name == y.Name && x.Age == y.Age;
}
...
}
And use it like this:
var intersect = a.Intersect(b, new ModelEqualityComparer());
If you want just LINQ solution:
List<Model> common = a
.Where(q => b.Any(w => w.Id == q.Id && w.Name == q.Name && q.Age == w.Age))
Related
I am writing linq query and finding it difficult to construct the logic using linq syntax. Basically I need to extract records that match the indexid and filter records based on months in the months array and year field. How do I check months array in the linq query
Here is what I am trying but not sure how to check for x.PriceDate.Month against months array
private Tuple<double?, double?> GetBenchMarkByYear(int year, int benchMark1, int[] months)
{
Tuple<double?, double?> benchMarkReturns;
double[] temp1 = null;
var benchMark1Returns = new double?[] { };
benchMark1Returns = GetViewService<MV_INDEX_PERFORMANCE>()
.Where(x => x.Mtd != null && x.IndexId == benchMark1 && x.PriceDate.Year == year && x.PriceDate.Month ).Select(x => x.Mtd)
.ToArray();
}
}
You can simply use the Any() method.
Which mean your condition will be as following:
benchMark1Returns = GetViewService<MV_INDEX_PERFORMANCE>()
.Where(x => x.Mtd != null && x.IndexId == benchMark1 && x.PriceDate.Year == year && months.Any(m=> m == x.PriceDate.Month))
.Select(x => x.Mtd)
.ToArray();
That if of course the entity x.PriceDate.Month is of type int since months if an array of integers.
I'm trying to filter a collection within an object in Entity Framework. I followed this example, which makes sense.
This is my resulting query:
var filteredClientEmp = context.Clients.Include(x => x.CompanyEmployee)
.Where(c => c.HrPersonId == paId && c.CompanyEmployee.Any(e => e.EmployeeBirthday != null && e.EmpType == 2 &&
e.LeftCompany == null))
.Select(c => new
{
c,
CompanyEmployee =
c.CompanyEmployee.Where(e => e.EmployeeBirthday != null && e.EmpType == 2 &&
e.LeftCompany == null)
})
.ToList()
.Select(pro => pro.c)
.ToList();
return filteredClientEmp;
However, when I inspect the filteredClientEmp object, it contains employee's with no birthday and records where the left company value is not equal to null.
The Client object has a non virtual list of Employee:
public List<Employee> CompanyEmployee { get; set; }
Why is this filtering not working?
Include() unconditionally loads all child entities. Because you project into an anonymous type with two properties:
c: the client with all its employees
CompanyEmployee: the employees for that client to whom your conditions apply
And then continue to project only c, this c still includes all employees. You need to overwrite c's CompanyEmployee collection with the filtered collection:
.Select(p => { p.c.CompanyEmployee = p.CompanyEmployee; return p.c; })
Your problem is in:
.Select(pro => pro.c).ToList();
You are not returning the clients with the list of employees filtered in:
CompanyEmployee = c.CompanyEmployee.Where(e => e.EmployeeBirthday != null && e.EmpType == 2 && e.LeftCompany == null)
In fact that property if the anonymous type is not used at all. Instead you are returning the filtered list of all clients which:
1) Have the specified HrPersonId and
2) Have at least one employee with a birthday, an employee type of 2 and have not left the company.
To return the Clients with the filtered list your final Select should look something like:
.Select(pro => { pro.c.CompanyEmployee = pro.CompanyEmployee; return pro.c; })
This question already has answers here:
Linq to SQL multiple conditional where clauses
(3 answers)
Closed 7 years ago.
I want to have multiple where clauses in linq but out of them only one should execute, i was trying something like this:
public JsonResult GetPost(int? id, int? tagid, DateTime? date)
{
var ret = from data in db.Posts.Include(x => x.Tags)
.Include(x => x.Neighbourhood)
.Where((x => x.NeighbourhoodId == id) || (y => y.PostedDate == date) || third condition).ToList()
but i was unable to put second and third condition there becoz after putting dot after y, i cant see any options.
Now, out of these three, only one parameter would have value and other two would have null so, it should checks for parameter only with value.
should i write query like this, is it correct way:
if (id != null)
{
//whole query here
}
else if (tagid != null)
{
//whole query here
}
else (date != null)
{
//whole query here
}
Is it the best way to do this or something else is possible. many many thnks in advance for any suggestion.
Something like this?
var ret = from data in db.Posts.Include(x => x.Tags)
.Include(x => x.Neighbourhood)
.Where(x => x.NeighbourhoodId == (id ?? x.NeighbourhoodId) &&
x.<condition> == (tagid ?? x.<condition>) &&
x.PostedDate == (date ?? x.PostedDate).ToList();
Or like this:
var ret = from data in db.Posts.Include(x => x.Tags)
.Include(x => x.Neighbourhood)
.Where(x => id.HasValue ? x.NeighbourhoodId == id :
tagid.HasValue ? x.<condition> == tagid :
x.PostedDate == date).ToList();
Another option is to build your query more dynamically. I think this also makes your code more human readable, and your conditions can be more complex if needed (for example, build your query inside a loop or something). And you can use this with any other operator, like Include etc. Once your query is built, you can call ToList().
var ret = db.Posts.Include(x => x.Tags).Include(x => x.Neighbourhood);
if (id != null)
{
ret = ret.Where((x => x.NeighbourhoodId == id);
}
else
{
...
}
var result = ret.ToList();
You could use the following:
var ret = from data in db.Posts.Include(x => x.Tags)
.Include(x => x.Neighbourhood)
.Where(x => id == null || x.NeighbourhoodId == id)
.Where(x => date == null || y.PostedDate == date)
.ToList();
If the paramter is null, the where-clauses returns every element of the sequence. If its not null it only returns the elements which matches.
This question already has answers here:
How to filter nested collection Entity Framework objects?
(3 answers)
Closed 7 years ago.
I have an object heirarchy:
DeathStar.Floors.Departments.Rooms
At the moment, I'm only selecting floors that contain departments that have a room containing rebel scum being intimidated or injected by a droid:
var rebelScum = deathStar.Floors.Where(
f=> f.Departments.Any(
d => d.Rooms.Any(
r => r.Occupant.Allegiance == "Rebel"
&& (r.InterrogationState == Interrogation.Intimidation
|| r.InterrogationState == Interrogation.FloatyStabbyDroid)
)
)
);
However, rebelScum will contain empty rooms in the same department as any rebel scum being interrogated.
Can I filter inside this .Where() to only return the occupied rooms?
IEnumerable<Room> roomsOccupiedByRebelScum = deathStar.Floors.SelectMany(f => f.Departments)
.SelectMany(d => d.Rooms)
.Where(r => r.Occupant != null && r.Occupant.Allegiance == "Rebel" &&
(r.InterrogationState == Interrogation.Intimidation || r.InterrogationState == Interrogation.FloatyStabbyDroid)
);
If you want to filter rooms, they must form the result of the query
This question already has answers here:
Creating reusable Linq queries
(6 answers)
Closed 8 years ago.
I have a query:
doc.NonFinancialAssetSection.NonFinancialAssets
.Where(m => m.Owner.Id == ownerId && m.InvestableAsset == true)
.Sum(s => s.CurrentValue);
I need to change the value of s.CurrentValue to s.ProposedValue, however rather than copying and pasting the query again, is there any way i can have this value dependant on a parameter passed into the controller?
Yes, you can do this:
var query = doc.NonFinancialAssetSection.NonFinancialAssets
.Where(m => m.Owner.Id == ownerId && m.InvestableAsset == true);
var sum = (condition)
? query.Sum(s => s.CurrentValue)
: query.Sum(s => s.ProposedValue);
You could also do this:
var sum = doc.NonFinancialAssetSection.NonFinancialAssets
.Where(m => m.Owner.Id == ownerId && m.InvestableAsset == true)
.Sum(s => (condition) ? s.CurrentValue : s.ProposedValue);
Or this:
Func<NonFinancialAsset, double> sumProperty = (condition)
? s => s.CurrentValue
: s => s.ProposedValue;
var sum = doc.NonFinancialAssetSection.NonFinancialAssets
.Where(m => m.Owner.Id == ownerId && m.InvestableAsset == true)
.Sum(sumProperty);