When I am accessing all cities my code is like this.
public IQueryable<City> GetAll()
{
var result = from s in this.Context.Cities.Include("States.Countries") select s;
return result;
}
This is working fine and including states and countires. I want to get cities by Country Id, below is my code. In the below code, I want to include States.Countires for each city. How can i do this ?
public IEnumerable<City> GetByCountriesId(int Id)
{
var result = from s in this.Context.Countries
join a in this.Context.States on s.Id equals a.Country_Id
join b in this.Context.Cities on a.Id equals b.States_Id
where s.Id == Id
select b;
return result;
}
Are you sure a city could belong to several states? IMHO you should have a one to many relationship, where an State
could have several Cities
and a City
should belong to one State
. The same happens with State
and Country
. I think you have pluralized those nav. property names ( States
in City
and Cities
in Country
) but there are not collections. In case you have those two one to many relationships in the same way that I describe above, you can write a query as I show as follow to achieve what you need:
var result = this.Context.Cities.Include(c=>c.State.Country).Where(c=>c.State.Country.Id==Id);
Is better use the DbExtensions.Include extension method because is strongly typed.
Now, maybe you can think this query could end with a NullReferenceException
due to the c.State.Country.Id
expression in case one of those nav. properties could be null
.But that is not going to happen because you need to set those navigation properties (or the FK properties in case that already exist in DB) when you need to save a new City
or State
in DB, in other word, they are required .
If you use Fluent Api to configure those relationships you will end with something like this:
modelBuilder.Entity<City>().HasRequired(c=>c.State).WithMany(s=>s.Cities).HasForeignKey(c=>c.State_Id);
modelBuilder.Entity<State>().HasRequired(s=>s.Country).WithMany(c=>c.States).HasForeignKey(s=>s.Country_Id);
public IEnumerable<City> GetByCountriesId(int id)
{
return from country in this.Context.Countries
where country.Id == id
from state in country.States
from c in this.Context.Cities.Include(c => c.States.Select(s => s.Countries))
where c.States.Any(s => s == state)
select c;
}
or, even better:
public IEnumerable<City> GetByCountryId(int id)
{
return from c in this.Context.Cities
.Include(c => c.States.Select(s => s.Countries))
where c.States.Any(s => s.Countries.Any(c => c.Id == id))
select c;
}
However – while it's clear why Country
has a States
collection and State
has a Cities
collection – why does your City
have a States
collection and your State
have a Countries
collection? Shouldn't these be State
and Country
properties, respectively?
Assuming your City
really does have a single State
, and your State
has a single Country
, this simplifies it a lot:
return from c in this.Context.Cities
.Include(c => c.State.Select(s => s.Country))
where c.State.Country.Id == id
select c;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.