Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C语言中的类链接最佳实践#_C#_Oop_Class_Coding Style - Fatal编程技术网

C# C语言中的类链接最佳实践#

C# C语言中的类链接最佳实践#,c#,oop,class,coding-style,C#,Oop,Class,Coding Style,首先,EF不是我们开发环境的选项,所以请不要回答“只使用EF”的问题 我认为这是一个相当标准的两难选择,所以我相信一定有一种大多数职业选手都能做到的方法,我只是没有偶然发现。。。所以我在这里希望你们能告诉我这是什么 假设您有以下数据库表: tblCompanies ID NAME tblDepartments ID COMPANY_ID NAME tblEmployees ID DEPARTMENT_ID FIRSTNAME LASTNAME 。。。在代码的类中表示这一点的

首先,EF不是我们开发环境的选项,所以请不要回答“只使用EF”的问题

我认为这是一个相当标准的两难选择,所以我相信一定有一种大多数职业选手都能做到的方法,我只是没有偶然发现。。。所以我在这里希望你们能告诉我这是什么

假设您有以下数据库表:

tblCompanies 
ID 
NAME

tblDepartments 
ID 
COMPANY_ID 
NAME

tblEmployees
ID 
DEPARTMENT_ID 
FIRSTNAME 
LASTNAME
。。。在代码的类中表示这一点的最佳方法是什么

我认为最好的方法是这样的:

public class Company
{
     public int ID { get; set; }
     public string Name { get; set; }
     public List<Department> Departments { get; set; }
}

public class Department
{
     public int ID { get; set; }
     public string Name { get; set; }
     public List<Employee> Employees { get; set; }
}

public class Employee
{
     public int ID { get; set; }
     public string FirstName { get; set;}
     public string LastName { get; set; }
}
public class Department
{
     public int ID { get; set; }
     public string Name { get; set; }
     public int CompanyID { get; set; }
     public List<Employee> Employees { get; set; }
}
上市公司
{
公共int ID{get;set;}
公共字符串名称{get;set;}
公共列表部门{get;set;}
}
公共课系
{
公共int ID{get;set;}
公共字符串名称{get;set;}
公共列表雇员{get;set;}
}
公营雇员
{
公共int ID{get;set;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
}
我相信这是“面向对象的正确方法”。然而,似乎总是发生这样的事情:

public class Company
{
     public int ID { get; set; }
     public string Name { get; set; }
     public List<Department> Departments { get; set; }
}

public class Department
{
     public int ID { get; set; }
     public string Name { get; set; }
     public List<Employee> Employees { get; set; }
}

public class Employee
{
     public int ID { get; set; }
     public string FirstName { get; set;}
     public string LastName { get; set; }
}
public class Department
{
     public int ID { get; set; }
     public string Name { get; set; }
     public int CompanyID { get; set; }
     public List<Employee> Employees { get; set; }
}
公共课部
{
公共int ID{get;set;}
公共字符串名称{get;set;}
public int CompanyID{get;set;}
公共列表雇员{get;set;}
}
。。。主要是因为当您从数据库中只提取一个部门时,您将只拥有公司ID,而不是完全填充公司类实例所需的所有其他属性

(我在这里使用了一个非常普通的示例,但我在当前项目中实际处理的示例有3个字段,用于将数据链接在一起,因此在几个类中使用相同的3个字段的想法对我来说似乎是错误的)


这些场景是否有最佳实践?虽然我不喜欢出于懒惰而将相同的数据存储在多个类中,但我也不喜欢返回一个只填充了一个字段的类实例,因为这就是我当时所拥有的一切

这是一个常见的问题,也是ORMs试图解决的问题。当然,这不是一件容易的事,这取决于你想要什么和你的限制是什么

只有两个基本选项可以保存一份信息。按照请求延迟加载数据,或者从一开始就加载所有数据(贪婪加载)。否则,您必须复制数据

通过延迟加载,您基本上可以进行设置,以便在导航到属性时调用数据库并获取加载表示正在访问的属性的实体所需的信息。要注意的棘手部分是选择N+1问题。当迭代一组父实体并在每个子实体上触发延迟加载时,就会遇到这个问题,从而导致对数据库的N+1调用以加载一组实体(1)及其子实体(N)

贪婪加载基本上是指加载您需要开始的所有内容。ORMs(在它们工作的地方)很好,因为它们通过LINQ处理许多细节,并创建可执行和可维护的解决方案,通常还允许您操纵贪婪和延迟加载的使用

另一个重要的问题是多对多关系。您需要确保不进行循环初始化,并获得循环依赖的所有包袱。我肯定还错过了很多

以我的拙见,我不太确定是否有一个最佳实践,正如有一些实践是不好的——没有什么是完美的。你可以:

  • 开始运行您自己的对象关系映射程序,以消除重复的ID

  • 使用更轻的ORM框架来处理其中的一些问题,从而消除重复的ID

  • 创建专门的查询以加载数据聚合,从而消除重复ID(*cough*DDD)

  • 只需像上面提到的那样保留ID的副本,而不用担心在域中创建显式关系模型


  • 这一点取决于您根据自己的约束条件选择最佳方案。这是一个深奥的话题,我的经验有限……因此,我要对我所说的话大加保留。

    我认为这取决于需求。您是否需要向上遍历(从部门获取公司、从员工获取部门等)。如果你这样做了,那么你最好提供一种方法来做到这一点。理想情况下,这将类似于公司或部门属性,当然,您不想获取您并不真正需要的数据,因此您可能会保留一个私人公司id,并拥有一个公共getCompany函数来查询数据。

    我相信这不是一个真正的OOP问题,在您的情况下,您只有一个数据库模型(类中的数据库表示)不包含任何逻辑,所有类都用作结构,这是将数据库映射到类-结构的正确方法。因此,在下一个表示程序逻辑的模块中,您必须将数据库模块映射到包含逻辑的真实类(我指的是实现它的方法)当然,如果你真的需要的话。所以我认为OO的问题应该在你的应用程序的逻辑部分。另一方面,你可以看看nhibernate,看看它是如何实现映射的,它会给你一个关于bes数据库模型实现的提示。

    我不认为有什么问题“最佳实践”手册适用于此类内容,当然这取决于您的课程将如何使用。但根据我个人的经验,我最终采用了以下方法:

    public class Company
    {
       public int ID { get; set; }
       public string Name { get; set; }
    
       public IEnumerable<Department> GetDepartments()
       {
          // Get departments here
       }
    }
    
    public class Department
    {
       public int ID { get; set; }
       public string Name { get; set; }
       protected int CompanyID { get; set; }
    
       private Company _Company;
       public Company Company
       {
          get
          {
             // Get company here
          } 
       }
    
       public IEnumberable<Employee> GetEmployees()
       {
          // Get employees here
       }
    }
    
    public class Employee
    {
       public int ID { get; set; }
       public string Name { get; set; }
       protected int DepartmentID { get; set; }
    
       private Department _Department;
       public Department Department
       {
          get
          {
             // Get department here
          } 
       }
    
       public IEnumberable<Employee> GetEmployees()
       {
          // Get employees here
       }
    }
    
    上市公司
    {
    公共int ID{get;set;}
    公共字符串名称{get;set;}
    公共IEnumerable GetDepartments()
    {
    //到这儿来
    }
    }
    公共课系
    {
    公共int ID{get;set;}
    公共字符串名称{get;set;}
    受保护的int CompanyID{get;set;}
    私营公司;