0

I have the following entities.

public class Country{
    public virtual int Id { get; private set; }
    public virtual string Name { get; set; }
    public virtual IList<City> Cities { get; set; }
}

public class City{
    public virtual int Id { get; private set; }
    public virtual string Name { get; set; }
    public virtual Country Country {
        get { return _country; }

    }

    private readonly Country _country;
}

But given the following code a user can do

  1. _country.Name = "newCountry";
  2. _country.Cities.Add(AnotherCity);
  3. _country.Cities[0].Name = "newCity" 4. _country.Cities[0].Country.Name = "Opps"

1-3 are ok but my problems are with #4. There is some need for me make this as a bi-directional One-Many mapping, But I would ideally wish that the reference of Country (including all its properties) in city entity be readonly. Is there a way I can do that? I tried

public interface IReadOnlyCountry {

    int Id { get; }
    string Name { get; }
    IList<City> Cities { get; }

}

public class Country : IReadOnlyCountry{
    public virtual int Id { get; private set; }
    public virtual string Name { get; set; }
    public virtual IList<City> Cities { get; set; }
}

public class City {
        public virtual int Id { get; private set; }
        public virtual string Name { get; set; }
        public virtual IReadOnlyCountry Country {
            get { return _country; }

        }

        private readonly Country _country;
    }

But its not working for Nhibernate (not sure if I am doing something wrong, or this is not possible). How do you handle such situations?

Umair Ahmed
  • 11,238
  • 5
  • 33
  • 39
  • 1
    Why dont you create two entities (Country and CountryInfo) and both are mapped using NHibernate .. and use CountryInfo as the type of the field in City – Mohamed Abed Oct 04 '11 at 13:25
  • Tried it. Working fine. I was thinking that Country is just adding functionality in ReadOnlyCountry. So it makes more sense in making ReadOnlyCountry a Base type. – Umair Ahmed Oct 05 '11 at 06:10

1 Answers1

1

Given that cities and countries don't change names often, I would make their properties readonly. Also, it is advisable to create a method on the Country class for adding cities so that the Country-City relationship is enforced:

public class Country
{
    public Country(string name)
    {
        this.Name = name;

    }

    // for NHibernate
    protected Country()
    {
        this.Cities = new List<City>();
    }

    public virtual int Id { get; private set; }
    public virtual string Name { get; private set; }
    public virtual IList<City> Cities { get; private set; }

    public virtual City AddCity(string name)
    { 
        var city = new City(this, name);
        this.Cities.Add(city);
        return city;
    }
}

public class City
{
    public City(Country country, string name)
    {
        this.Country = country;
        this.Name = name;
    }

    // for NHibernate
    protected City()
    {
    }

    public virtual int Id { get; private set; }
    public virtual string Name { get; private set; }
    public virtual Country Country { get; private set; }
}

Now the name is readonly no matter how you access the entity. If however you have a case where you would like to be able to change the name of the country or city, accessing the Country entity from the city is just one way to access it and there is nothing wrong with being able to change the name using the code in #4.

However, you can make the code you specified work by changing the default access strategy in the FluentNHibernate mapping for the Country property on the City entity so that it stores the value in the _country field as opposed to going through the property.

eulerfx
  • 36,769
  • 7
  • 61
  • 83
  • Thanks for your reply eulerfx. I am really interested in making my code work. but cant seem to find decent documentation on setting access strategy on Country to field. :( – Umair Ahmed Oct 22 '11 at 20:43
  • I found this http://stackoverflow.com/questions/672032/fluent-nhibernate-working-with-interfaces/2114087#2114087 very helpful. Just what i was looking. – Umair Ahmed Oct 23 '11 at 04:51