【问题标题】:How should domain classes be designed?领域类应该如何设计?
【发布时间】:2012-01-03 14:00:10
【问题描述】:

我想展示一个示例和一些要求,并想了解最好的领域模型应该是什么。

数据库是:

One Country has Many Cities.
One City has many Towns

两个表都有 Id 列。

在我的 C# 中,我有

public class Country
{
  public List<City> Cities {get;set;}
  public int Id;
}

public class City
{
  public int Id {get;set;}
  public int CountryId {get;set;}
}
  1. 当我想更新一个城市时,我可以只取国家的 ID 并更新它。所以这个设计有效。
  2. 当我想插入一个新的 城市,我可以将城市对象插入到 Db 中。所以这个设计 有效。

  3. 当我想删除一个城市时,我获取城市的 ID 并 从 Db 中删除它。所以这个设计很有效。

  4. 当我想展示一个城市时, 我还需要 UI 网格中的国家列,所以这个设计不起作用。

然后我会从国家/地区 id 列中获取每个城市的国家/地区,这很痛苦。

如果 Country 具有 City 类的属性,那么我将不得不为所有城市对象创建 Country 对象,并且在更新、插入和删除期间我不需要 Country 对象 - 我只需要 CountryId。

所以我的问题是:

  • 我应该如何设计它们?
  • 我是否应该在 城市级?
  • 我应该尝试您推荐的其他方法吗?

【问题讨论】:

  • 这就是为什么建议有一组单独的模型和视图模型类;映射到您在数据库中设置事物的方式的模型类和映射到您的视图设置方式的视图模型类。
  • 您是在使用关系数据库还是其他类型的数据库,或者所有内容都在内存中?
  • 我正在使用数据库。在视图模型中,我应该从 Db 中检索每个模型的相关实体吗?我目前正在使用基于模型类顶部的视图模型。问题是我必须为每个城市对象获取国家名称,这意味着我必须调用具有国家名称列的不同选择查询,这也意味着模型是通过首先创建城市然后创建国家对象来创建的城市。

标签: c# asp.net


【解决方案1】:

如果 Country 具有 City 类的属性,那么我必须为所有城市对象创建 Country 对象,并且在更新、插入和删除期间我不需要 Country 对象 - 我只需要 CountryId。

在所有City 对象中填充Country 对象有什么问题?它们不需要填充,您可以简单地存储 ID。这在 ORM 世界中被称为延迟加载(可能在外部也是如此)。

例如:

public class Country
{
    private List<City> _cities;

    public int Id { get;set; }
    public IEnumerable<City> Cities
    {
        get
        {
            // load on demand
            if (_cities == null)
                _cities = LoadCities(Id);

            return _cities;
        }
    }
}

public class City
{
    public int Id { get;set; }
    public Country Country { get;set; } 
}

归结为关系的哪一方处于控制之中。国家是否负责更新其所有子项(级联更新),还是您只是希望城市这样做?无论哪种方式,持有 Country 对象都比让 ID 浮动更不以数据库为中心。

如果您在 Cities 和 Country 表(而不是 LoadCities)之间执行连接,那么无论如何您都将拥有每个城市的国家/地区 ID,并预取数据。

【讨论】:

  • 延迟加载以获取某个城市的国家/地区现在和以后加载一些属性...你确定
  • @KnowledgeSeeker 这只是一个例子,我不会那样做。与数据库相比,Chunky 比健谈要好,所以在这个例子中加入整个团队会好得多。但是为了更新你的城市,你仍然应该坚持使用 Country 对象,而不仅仅是一个 Id。然后,您可以根据其 ID 延迟加载。
  • @KnowledgeSeeker 顺便说一句,NHibernate 和其他 1001 个 ORM 通常会为您完成所有这些工作,如果您想花更多时间编写 UI 和业务逻辑
  • 如果您尝试序列化这些对象中的任何一个,这不会导致问题吗?它创建一个循环引用。
  • 加上我依赖于 orm。我想使用存储过程,所以我可以创建作业和检索所有信息,但只是为了可视化结果,我将不得不添加类属性......必须有一个技巧,可能只是添加 id 和 name 列相关实体
【解决方案2】:

您为什么不直接从 City 添加对 Country 对象的反向引用?这样,如果您需要国家/地区的名称,您可以这样做:

string countryname = city.Country.Name;

这就是类似 ORM 的实体框架默认的设计方式

【讨论】:

    猜你喜欢
    • 2011-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多