非常常见的问题:部门和员工
数据库两个表部门表和员工表,这里只列出部分关键字段
部门表:部门编号,部门名称...
员工表:员工编号,员工姓名,所属部门ID...
麻烦是业务逻辑层员工对象和数据层员工对象的设计:
//雇员类
class Employee
{
public string empId;//雇员ID
public string empName;//雇员姓名
public string depID;//部门ID
}
//部门类
class Department
{
public string depId;//部门ID
public string depName;//部门名
}
//数据访问层雇员类
class EmployeeDAC
{
//插入一个雇员
public void AddEmployee(Employee emp)
{
}
//修改一个雇员
public void ModifyEmployee(Employee emp)
{
}
//删除一个雇员
public void DeleteEmployee(Employee emp)
{
}
}
困惑的地方:
最终用户在界面上看到的都是有意义的名称,而不是哪些ID和编号,但数据库里和程序里有意义的就是这些ID和编号
比如查看员工信息,显示的总是员工所在部门的名称而不是部门编号,通常的做法就是查询数据库时使用连接,如果使用连接
我一般让这个检索员工信息的方法返回一个Dataset或者ArrayList
这只是一个小例子,大部分情况都这复杂,一个数据表有很几个外键,响应的对象很有多ID,显示的时候更麻烦
这种情况该如何设计类呢?
16 个解决方案
这个不是类设计的问题,涉及的问题,而是数据库设计的问题。比如说,如果在员工表里面增加一个部门名称列,则显示员工信息的时候就很方便,不用关联到部门表,但这样会造成数据冗余,当修改部门名称的时候,两个表都要同时修改,这就是矛盾。
class Employee
{
public string empId;//雇员ID
public string empName;//雇员姓名
public string depID;//部门ID
}
变成
class Employee
{
public string empId;//雇员ID
public string empName;//雇员姓名
public Department department ;//部门
}
把每个外键都建成相应的实体类,这样就使保存的时候比较麻烦,但查询的时候和方便
如果是一对多的就建立一个对象集合ArrayList
具体要分清业务逻辑,是一对多,还是一对一,还是多对多
一般都用联查的,我个人是单独封个DLL的类库,调用它来完成ID和名称的转换,也希望有个转换的函数,向ASP表单一样,值和显示的名称可以分开来,期待高手.
期待更多的人讨论,因为这个问题太普遍了,每次碰到我都会想是否有好的办法
就象xh831213 那样设计,那创建employee对象的时候也要创建一个部门对象了
总之要么查询麻烦,要么更新麻烦,要么显示麻烦
还有别的解决方案吗?
没有十全十美的办法
基本上都是根据分析好的业务来做选择
更新数据量大的就直接选择外键方式
要是数据量不是很大,为了查询方便就使用类关联类的方式
要是数据量又大又要查询方便,最好就不要使用类了,直接使用存储过程查询数据库
其实oo并不适用于任何地方,该舍弃的时候就要舍弃
是你说数据库设计问题吗,还是说类啊,你要查询不麻烦,那就一张表解决问题,
但在大的数据库上会产生很大的数据冗余,一般用第三范式就差不多了,
或BC范式就完全够了!这也算是设计的一个规范吧,建议你看一下数据库概论
有的时候为了偷懒,比如部门名称不允许重复,那干脆我就直接用部门名称做为主键,员工表里也有部门名称,这样在在对员工信息进行增删改查时候不需要用连接来获取部门名称了
大家觉得这样做如何?
有什么副作用吗?
加一个逻辑类吧,里面放页面要用的属性就行了,再通过逻辑方法取值.呵呵.
class Employee
{
public string empId;//雇员ID
public string empName;//雇员姓名
public string depID;//部门ID
}
变成
class Employee
{
public string empId;//雇员ID
public string empName;//雇员姓名
public Department department ;//部门
{
get
{
return 根据depID返回的department
}
}
public string depID;//部门ID
}
这样可以么?
ahshow
---------
这个问题确实不是什么难题,这么多软件也做 了过来.
总是想知道是否有更好解决办法?
这种问题在开发过程中是最常见一种,不同的人有不着不同的方法.
class Employee
{
public string empId;//雇员ID
public string empName;//雇员姓名
public string depID;//部门ID
}
变成
class Employee
{
public string empId;//雇员ID
public string empName;//雇员姓名
public Department department ;//部门
}
或者变成
class Employee
{
public string empId;//雇员ID
public string empName;//雇员姓名
public string depID;//部门ID
public string depName;//部门名称
}
用户显示的时返回两表关联数据视图(包含有部门名称),而插入时,可以传递ID(插入前转换,但这种方法不适合应用大量数量,如销售单中的货品ID转换,如果大量的转换让程序与数据库之间来回,除性能以外,速也是个问题),也可以传递名称或编码(如货品编码,更新时转换,将所传入的编码集作为条件,返回ID集,再更新所有的ID,即一次性转换,适合大量的数据),另一个就是在界面转换,即在控件或单元格中利用录入时或选择时进行转换,可以利用控件或单元格的Tag属性保存,但这种就需要在界面有严格的控制,否则可能对应ID会出错.还有一种就是利用存储过程来在后台更新和转换.
以上仅是个人应用的方法.
不知各位还有什么其他办法