Reputation: 229
I need to create a model and method which will be populated with the lists of relevant models.
My model looks like:
public class SearchHierarchyModel
{
public IList<Continent> Continent { get; set; }
public IList<Country> Country { get; set; }
public IList<City> City { get; set; }
}
My methods should do something like:
public IList<SearchHierarchyModel> GetHierarchyFull(int Coninent_Id)
{
//pseduocode now
create lists of countries based on continent id
create lists of cities based on countries id from the prev. step
return a list of lists with relevant countries and cities
}
Model classes
public class Contient
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Country
{
public int Id { get; set; }
public string Name { get; set; }
public int ContientId { get; set; }
}
public class City
{
public int Id { get; set; }
public string Name { get; set; }
public int CityId { get; set; }
}
Perhaps there is a better way to implement such kind of hierarchy? Any ideas how to do this? Maybe the the model should look differently?
Upvotes: 0
Views: 97
Reputation: 3720
Depending on how your relationships are setup, it would be possible to do something similar to.
public IList<SearchHierarchyModel> GetHierarchyFull(int Continent_Id)
{
var continent = db.Continents.FirstOrDefault(c => c.Id == Continent_Id);
//Get all countries with a specified ContinentId
var countryList = db.Countries.Where(c => c.ContinentId == Continent_Id);
//Get all cities that have a matching CountryId from any country in the first list.
var cityList = db.Cities.Where(c => countryList.Any(cl => cl.Id == c.CountryId)).ToList();
//We need to get the original countryList as a true list rather than a collection of entities.
//If we had called ToList above, it would error out.
//If we had called ToList in the ForEach loop, we also would have issues.
var countryList2 = countryList.ToList();
var searchList = new List<SearchHierarchyModel>
{
new SearchHierarchyModel()
{
Continent = new List<Continent> { continent },
Country = countryList2,
City = cityList
}
};
return searchList;
}
Now some comments about the above. It seems like to me, you simply want a list of countries and their cities for a given Continent. If that's the case, entity framework makes it even easier for you.
I would change my core models to be:
public class Continent
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Country> Countries { get; set; }
}
public class Country
{
public int Id { get; set; }
public string Name { get; set; }
public int ContinentId { get; set; }
public virtual Continent Continent { get; set; }
public virtual ICollection<City> Cities { get; set; }
}
public class City
{
public int Id { get; set; }
public string Name { get; set; }
public int CountryId { get; set; }
public virtual Country Country { get; set; }
}
Then I'd set the hierarchy model to:
public class SearchHierarchyModel
{
public Continent Continent { get; set; }
public Country Country { get; set; }
public City City { get; set; }
}
Now we can change the search function to be:
public IList<SearchHierarchyModel> GetHierarchyFull(int Continent_Id)
{
var countries = db.Countries.Where(c => c.ContinentId == Continent_Id);
var cities = db.Cities.Where(c => countries.Any(co => co.Id == c.Id));
var searchList = new List<SearchHierarchyModel>();
foreach (var item in cities)
{
var newItem = new SearchHierarchyModel
{
Continent = item.Country.Continent,
Country = item.Country,
City = item
};
searchList.Add(newItem);
}
return searchList;
}
Now rather than iterating over a list of lists, we're iterating over a list of all the possible return values. Plus with the modification of the models, the relationships between the models are explicitly defined. This means I can more easily reference and interact with them.
And here's a search method that does the traversal of the objects in reverse using Linq, cutting out the foreach loop and removing all the extra lists.
public IList<SearchHierarchyModel> GetHierarchyFull(int Continent_Id)
{
var continent = db.Continents.FirstOrDefault(c => c.Id == Continent_Id);
if (continent == null)
return null;
var searchList = (from item in continent.Countries
from city in item.Cities
select new SearchHierarchyModel
{
Continent = continent,
Country = item,
City = city
}).ToList();
return searchList;
}
Upvotes: 2