3

我有几种不同类型的公司可以访问我的 Web 应用程序,例如

不同类型的公司:

客户供应商代理

每个人在数据库中都有自己的表,链接到主表 Company,该表存储所有常见数据,例如 Address、Tel、Email、TypeOfCompany,并带有 FK 到相关表(Client 等)...

在整个应用程序中处理此 OO 的最佳方法是什么?

我目前正在做类似的事情:

public class CompanyDTO
{
  public int Id {get;set;}
  public string Name {get;set;}
  public Address Address {get;set;}
  public string Type {get;set;} //type of company
  //etc...
}

然后从该类继承并添加其他属性,例如

public class ClientDTO : CompanyDTO
{
 public string Key {get;set;}
 public Address Billing {get;set;}
}

但是,例如,我有时会发现它有问题

  1. 供应商用户想要访问:AllCompanies,- 显示所有公司的列表
  2. 然后供应商公司的用户想要查看特定公司的详细信息,现在如果是客户,我需要显示 ClientDTO 还是 SupplierDTO?在这种情况下,我想向特定公司展示完整的详细信息

处理这个问题的最佳方法是什么?

例如GetCompanyByID(int companyid);,或者GetClientByID(int clientid);我应该在两个实例中返回什么类型的对象,假设我想要两个实例中的客户详细信息......

4

2 回答 2

3

有趣的是,数据库不理解派生、聚合和封装等 OO 实践。这是一个不幸的失败,但仍然只是所谓的“数据库阻抗不匹配”的一部分。

您尝试做的事情很常见,有几种解决方案......

首先是存储数据模型的选择。基本上有三种可能。

  1. 像你做的那样拆分表格。
  2. 为同一个表中的所有派生类型声明所有字段。
  3. 使用 blob 字段 (json/xml/whatever) 来容纳不常见的字段。

其次是您提出的问题,即从数据库中请求数据。主要是围绕“常见”基本类型列表的请求以及如何访问它们不共享的不常见字段。同样有几种可能性。

  1. 列出基本类型时,仅返回那些公共字段。然后一次性发出后续查询以延迟加载其他字段。
  2. 列出基本类型时,所需的所有其他表也外部连接到主表,以确保所有字段都可用于完全实例化对象模型。
  3. 列出基本类型时,会返回多个结果集,每个结果集可能需要一个“子类型”表。然后,客户端将记录拼凑在一起构建对象模型,直到完成。

不是一个详尽的清单,而是一个开始。出于这个原因,我个人更喜欢避免像您描述的那样的数据模型。本质上,我的偏好是让数据模型定义所有字段的联合(模型#2),然后使用业务层来确定公开、验证、需要哪些属性等。我还使用了上面的模型#3,使用多个值的 blob 字段,它也可以根据需要运行良好。模型 #3 优于 #2 的唯一缺点是您将无法对这些字段进行查询或排序。最终,这两种方法仍然需要涉及的业务逻辑层知道要公开哪些数据。

记住数据库是愚蠢的,这样对待它们,你会相处得很好。(注意:此建议不适用于人,仅适用于数据库)

于 2011-07-20T21:58:08.893 回答
1

我要访问:AllCompanies,- 显示所有公司的列表

当您想要一份公司列表时,您不是要求提供实例CompanyDTO描述的一般细节吗?也许您的数据访问(服务、存储库等)可能如下所示:

public class CompanyRepository : ICompanyRepository
{
    public IEnumerable<CompanyDTO> GetCompanies()
    {
        // get companies and map them to CompanyDTO objects as necessary
    }
}

然后你问(嗯,有一个问号)

然后我想查看特定公司的详细信息,现在如果是客户,我需要显示 ClientDTO 还是 SupplierDTO?

我假设这将是一个单独的视图,或者至少分解为一个单独的部分视图。但是,您可以使用显示模板来描述您的子公司类型,因为您已经描述了上面的继承。

我会假装你向我们展示了你的控制器,它看起来像这样:

public class CompanyController : Controller
{
    public ActionResult Details(int id)
    {
        CompanyRepository repo = new CompanyRepository();
        return View(repo.GetCompanyById(id));
    }
}

然后,添加一个名为 的强类型视图Details,它继承一个CompanyDTO对象,并添加对 的调用Html.DisplayForModel()

<%--some scaffolded code ommitted for brevity--%>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <%= Html.DisplayForModel() %>

</asp:Content>

然后,这里是显示模板的用武之地。添加一个文件夹

~/Views/Company/DisplayTemplates

然后将3 个 strong-typed部分视图添加到该文件夹​​中- 每个子类型一个。Visual Studio 将帮助您:

  1. 右键单击DisplayTemplates文件夹 --> 添加视图...
  2. 将其命名为“ClientDTO”(这很重要)
  3. 勾选“创建局部视图”
  4. 勾选“创建强类型视图”
  5. 选择ClientDTO班级
  6. 选择Details查看内容(这将为您提供一些自动生成的标记)
  7. 点击添加

对其他子类型重复此过程,将根据传递给您的详细信息视图的模型的类型呈现正确的模板。

于 2011-07-20T21:32:27.523 回答