基于公司而不是用户的复杂领域模型
我有一些不同类型的公司可以访问我的网络应用程序,例如
不同类型的公司:
客户 供应商 每个代理
在数据库中都有自己的表,链接到主表公司,该表存储所有常见数据,例如地址、电话、电子邮件、公司类型以及相关表的 FK(客户等)...
最好的方法是什么在我的应用程序中处理这个 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;}
}
但是我有时发现它有问题,例如
- 供应商用户想要访问:AllCompanies, - 显示所有公司的列表
- 然后供应商公司的用户想要查看特定公司详细信息,现在如果是客户,我需要显示 ClientDTO 还是SupplierDTO?在本例中,我想向特定公司展示完整详细信息
处理此问题的最佳方法是什么?
例如 GetCompanyByID(int companyid);
或 GetClientByID(int clientid);
我应该在这两个实例中返回什么类型的对象,假设我想在这两个实例中获得客户详细信息...
I have a few different types of companies that can access my web application e.g
Different types of Companies:
Client
Supplier
Agent
Each have their own table in the database, linked to the main table Company which stores all common data e.g. Address, Tel, Email, TypeOfCompany with a FK to the relevant table (Client etc.)...
What is the best way to handle this OO throughout my app?
I currently do something like:
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...
}
then inherit from that class and add aditional properties e.g.
public class ClientDTO : CompanyDTO
{
public string Key {get;set;}
public Address Billing {get;set;}
}
However I am finding it problematic at times for example
- Supplier user wants to access: AllCompanies, - show a list of all companies
- Then the user from the Supplier Company wants to view a specific companies detail, now if it is a client I will need to show ClientDTO or SupplierDTO? In this instance I want to show that specific companies Full details
What would be the best way to handle this?
e.g. GetCompanyByID(int companyid);
or GetClientByID(int clientid);
What type of object should I return in both instances, presuming I want Client details in both instances...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
有趣的是,数据库不理解诸如派生、聚合和封装之类的面向对象实践。这是一个不幸的失败,但仍然只是总体上称为“数据库阻抗不匹配”。
您尝试做的事情很常见,有几种解决方案......
首先是存储的数据模型的选择。基本上有三种可能性。
其次是你提出的问题,从数据库请求数据。主要是围绕“公共”基本类型列表的请求以及如何访问它们不共享的不常见字段。同样有几种可能性。
不是详尽的清单,而是一个开始。就我个人而言,出于这个原因,我更喜欢避免像您所描述的那样的数据模型。本质上,我的偏好是让数据模型定义所有字段的并集(模型#2),然后使用业务层来确定公开、验证、需要哪些属性等。我还使用了上面的模型#3,使用blob 字段用于多个值,并且根据需要它也可以很好地工作。模型 #3 相对于模型 #2 的唯一缺点是您将无法对这些字段进行查询或排序。最终,这两种方法仍然需要涉及的业务逻辑层来了解要公开哪些数据。
记住数据库是愚蠢的,这样对待它们,你就会相处得很好。 (注意:这个建议不适用于人,仅适用于数据库)
Funny how databases don't understand OO practices like derivation, aggregation, and encapsulation. It is an unfortunate failing but still only a part of what is overall referred to as "database impedance mismatch".
What your attempting to do is common enough there are several solutions...
Firstly there is the choice of the data model stored. There are basically three possibilities.
Secondly there is the issue you bring up, requesting the data from the database. Primarily this is centered around the request of a list of the 'common' base type and how to then access the uncommon fields that they don't share. Again there are several possibilities.
Not an exhaustive list, but a start. Personally I prefer to avoid data models like the one you describe for this reason. Essentially my preference is to have the data model define the union of all fields (model #2), and then use a business layer to determine what properties are exposed, validated, required, etc. I have also used model #3 above, using blob fields for multiple values, and it works well enough also depending upon need. The only downside to model #3 over #2 is that you will not be able to query or sort on those fields. Ultimately either approach still needs the business logic layer involved to know what data to expose.
Remember databases are stupid, treat them as such and you will get along well. (note: this advice does not work on people, just databases)
当您需要公司列表时,您不是在询问
CompanyDTO
实例描述的一般详细信息吗?也许您的数据访问(服务、存储库等)可能如下所示:然后您问(好吧,有一个问号)
我假设这将是一个单独的视图,或者至少分解为单独的部分视图。但是,您可以使用 显示模板 来描述您的子公司类型,因为您在上面描述了继承。
我假设您向我们展示了您的控制器,它看起来像这样:
然后,添加一个名为
Details
的强类型视图,该视图继承CompanyDTO
对象,并添加对Html.DisplayForModel()
:然后,这就是显示模板的用武之地。添加文件夹:
然后向该文件夹添加3个强类型, 部分视图——每种子类型一个。 Visual Studio 将帮助您完成此操作:
DisplayTemplates
文件夹 -->添加视图...ClientDTO
类Details
对于视图内容(这将为您提供一些自动生成的标记)对其他子类型重复此过程,将根据传递到详细信息视图的模型的子类型呈现正确的模板。
When you want a list of companies, aren't you asking for the general details that instances of
CompanyDTO
describe? Maybe your data access (service, repository, etc) could look like:Then you asked (well, there is a question mark)
I'm assuming this would be a separate view, or at least broken down into a separate partial views. But, you could use Display Templates to describe your child types of companies since you've describes an inheritance above.
I will pretend you showed us your controller and it looks like this:
Then, add a strongly-typed view named
Details
, that inherits aCompanyDTO
object, and add a call toHtml.DisplayForModel()
:Then, here's where display templates come in. Add a folder:
Then add to that folder 3 strongly-typed, partial views--one for each child type. Visual Studio will help you with this:
DisplayTemplates
folder --> Add View...ClientDTO
classDetails
for view content (this will give you some auto generated markup)Repeat this process for other child types and the correct template will be rendered based on the child type of the model passed to your Details view.