CSharpLearning
CSharpLearning

Reputation: 129

Data modeling for Country,Region,City

Im want to create a data structure for using within my MVC3 application. The site holds videos uploaded by users, I want to be able of setting up a location for the video so later on you can search based on the country, region or city.

The modeling of those entities is not a big problem to me, my question is which class attribute should I use for my video entity.

public class Country
{
 int CountryId
 string CountryName
}

public class Region
{
 int RegionId
 string RegionName
 int FK_CountryId
}

public class City
{
 int CityId
 string CityName
int FK_CountryId
int FK_RegionId
}

........

public class Video
{
int VideoId;
string VideoName;
**Location VideoLocation;**
}

**public class Location
{
int LocationId;
Country CountrId;
Region RegionId;
City CityId;
}**

My initial idea, but I think it is not a really good design since you can have 2 identical rows for a Location, where it should be ideal to keep a unique reference to Locations

What do you think in terms of good design and performance?

Upvotes: 1

Views: 2330

Answers (1)

Sebastian Siek
Sebastian Siek

Reputation: 2075

That is everyone's nightmare I guess. Well...at least that was my nightmare when designing one of the applications.

Depending on your secenario you might keep countries, cities, regions as different entities. Everything is find with that approach until you want the user to select either country, region or city. Looks like you would need to have nullable fields, which is not really the best practice, because you would then have to fully rely on application logic to maintain data integrity.

Example of that approach would be:

public class Country
{
    public string Code { get; set; } //country ID would not make sense in this approach
    public string Name { get; set; }
}

public class Region
{
    public string Code { get; set; }
    public string Name { get; set; }
    public string CountryCode { get; set; } //1 region is assigned to only 1 country
}

public class City
{
    public string Code { get; set; }
    public string Name { get; set; }
    public string RegionCode { get; set; } //1 city is assigned to only 1 region
}

It looks good, simple to understand but think about the table where you capture what's been selected. If you only care about city (last item in dependency list), it's all clear and fine.

public class UserSelectionWithCityOnly
{
    public string CityCode { get; set; }
}

Pretty easy and straight forward? Looks like it is. Consider the scenario where you can select either country,city or region....it get's really messy:

public class UserSelectionWithEitherSelected
{
    public string? CityCode { get; set; }
    public string? RegionCode { get; set; }
    public string? CountryCode { get; set; }
}

well...you could always check if CityCode.HasValue, but from DB point of view that would be a nullable field, which can add dirty data (should be fine if you are not pedantic about having neat and clean DB)

So they way I solve this was by creating one hierarchical table with parent item id :

public class MySolutionForDestinations
{
    public int DestinationId { get; set; } //primary key
    public int ParentDestinationId { get; set; }
    public string Code { get; set; }
    public string Name { get; set; }
    public DestinationLevel Level { get; set; }
}

public enum DestinationLevel
{
    Country = 0,
    Region = 1,
    City = 2
}

it's probably not the most elegant solution, but it works really well. In this approach you only care about DestinationId which can be a country Id, region Id or a city Id, so you would definitely avoid having dirty data and can implement 1 to 1 mapping.

Hope this will be usefull

Upvotes: 1

Related Questions