Reputation: 11
I have a database scheme with 3 tables. One for requisitions, one for hospitals, and one joining the two (many-to-many relationship).
I'd like to list all requisitions in the database that are linked to a selected hospital.
This is what I have so far:
var valgtSykehus = Db.Sykehus.Where(n => n.Navn == sykehus).Single(); //this gives me a variable with my current hospital. I want to list all requistions that contains this.
var Rekvisisjoner = Db.Rekvisisjoner
.Where(r => r.Arkivert == true) //get only archived requsitions
.Include(p1 => p1.Sykehus) //include hospitals
.ToList() //this generates a list of -all- requisitions with the hospitals they are attached to.
.Where(x => x.Created > DateTime.Now.AddYears(-3)) /only go 3 years back
.Where(x => x.Sykehus.Contains(valgtSykehus)); //here is the problem. I want to discard all requisitions that does NOT contain the hospital in the valgtSykehus variable
Anyway, this gives me zero requistions, but if I skip the last line, I get all archived requistions.
Upvotes: 1
Views: 390
Reputation: 11
Oh my. I just realised that none of the archived requisitions contains any connections to the hospitals, as they apparently are removed one-by-one when the requisition is processed in the program.
I figured this out while trying to reverse the query, so thanks for that tip.
Upvotes: 0
Reputation: 205599
x.Sykehus.Contains(valgtSykehus)
executes in LINQ to Objects context (due to the intermediate ToList
call) and most likely uses reference equality, which normally should work as soon as you use tracking queries.
Still, it's safer and also more efficient to do the whole thing with a single db query using Any
condition with primitive key. Something like this:
var Rekvisisjoner = Db.Rekvisisjoner
.Include(r => r.Sykehus) //include hospitals
.Where(r => r.Arkivert == true) //get only archived requsitions the hospitals they are attached to.
.Where(r => r.Created > DateTime.Now.AddYears(-3)) /only go 3 years back
.Where(r => r.Sykehus.Any(s => s.Navn == sykehus));
If there is an issues with using DateTime.Now.AddYears(-3)
inside the query, just put into variable outside of the query and use it inside.
var minDate = DateTime.Now.AddYears(-3);
var Rekvisisjoner =
// ...
.Where(r => r.Created > minDate)
//...
Upvotes: 1
Reputation: 9713
The issue may lie in the implementation of Contains
. Contains
has to check equality somehow. Anyway, if your valgtSykehus
object is logically contained in x.Sykehus
(i.e. has the same data), but not exactly the same object (i.e. the same reference), it's possible that Contains
fails to find it, due to the default implementation of ==
in reference types (==
is true, if the objects are exactly the same reference, false
otherwise, even though all the data is the same).
You could try the following:
var Rekvisisjoner = Db.Rekvisisjoner
.Where(r => r.Arkivert == true)
.Include(p1 => p1.Sykehus)
.ToList()
.Where(x => x.Created > DateTime.Now.AddYears(-3))
.Where(x => x.Sykehus.Any(sh => sh.Id == valgtSykehus.Id));
If Id
(or whatever your ID property is named) is a value field (most likely) this will return true
whenever the ID of an Sykehus
matches the ID of valgtSykehus
.
Upvotes: 0