如何从一端定义双向一对多关系中的ReadOnly实体?

时间:2011-10-04 10:35:17

标签: c# fluent-nhibernate domain-driven-design

我有以下实体。

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;
}

但是,如果用户可以执行以下代码

  1. _country.Name =“newCountry”;
  2. _country.Cities.Add(AnotherCity);
  3. _country.Cities [0] .Name =“newCity” 的 4。 _country.Cities [0] .Country.Name =“Opps”
  4. 1-3可以,但我的问题是#4。我需要将其作为双向一对多映射,但我理想的是希望城市实体中Country(包括其所有属性)的引用是只读的。有没有办法可以做到这一点?我试过了

    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;
        }
    

    但它不适合Nhibernate(不确定我做错了什么,或者这是不可能的)。你是如何处理这种情况的?

1 个答案:

答案 0 :(得分:1)

鉴于城市和国家不经常更改名称,我会将其属性设为只读。此外,建议在Country类上创建一个方法来添加城市,以便强制实施Country-City关系:

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; }
}

现在无论您如何访问实体,名称都是只读的。但是,如果您希望能够更改国家或城市的名称,则从城市访问Country实体只是访问它的一种方式,使用更改名称没有任何问题。 #4中的代码。

但是,您可以通过更改City实体上Country属性的FluentNHibernate映射中的默认访问策略来使您指定的代码工作,以便将值存储在_country字段中,而不是通过属性。 / p>