2017-08-12 50 views
1

我試圖從數據庫中提取記錄。在樹結構中從數據庫提取記錄

我的數據庫表:

  1. 部門
  2. EmployeeDepartments (中間表的部門--->員工)
  3. 員工
  4. EmployeeLocations (中間表的員工 - - >位置)
  5. 地址

上表包含大量記錄。

enter image description here

我試了一下:

我的第一種方法:

using(SQLConnection con = new SQLConnection()) 
{ 
    //Get all the departments 
    List<Department> departmentList = sp.GetAllDeparments(); 

    foreach(Deparment deparment in departmentList){ 

    //Get all employees 
    List<Employee> employeeList= sp.GetEmployeesByDepartment(departmentId); 

     foreach(Employee employee in employeeList){ 

      //Get all locations 
      List<Location> locationList= sp.GetLocationsByEmployee(employeeId); 

      foreach(Location location in locationList){ 
        //Code for location generation for PDF. 
      } 
     } 
    } 
} 

我的數據會根據以下的結構產生3210如果我在foreach循環中訪問數據庫,上面的代碼需要大約6分鐘的時間。

我的第二個辦法:

//Get all the departments 
List<Department> departmentList = sp.GetAllDeparments(); 

//Get all employees 
List<Employee> employeeList= sp.GetAllEmployees(); 

//Get all locations 
List<Location> locationList= sp.GetAllLocations(); 

//Get EmployeeLocations List<EmployeeLocations> emplocationList= 
sp.GetAllEmployeeLocations(); 

//Get EmployeeDepartments List<EmployeeDepartments> empDepList= 
sp.GetAllEmployeeDepartments(); 

foreach(Deparment deparment in departmentList){ 

    foreach(Employee employee in employeeList){ 

     foreach(Location location in locationList){ 

     } 
    } 
} 

我從上面提到的所有表獲取所有記錄,並在代碼的foreach使用LINQ操縱。因此,將時間從6分鐘縮短到4分鐘。

我的問題: 什麼是在儘可能最短的時間獲取數據的有效方法。在這種情況下?

我需要在上圖中操縱的數據。

+0

你的問題不是關於iText或關於PDF。 –

+0

我會說第二種方法,但結合正確的快速查找數據結構來查找部門員工和員工位置。數據獲取部分需要多長時間(在'foreach'之前)? –

+0

即使我正在使用第二種方法,一次獲取數據並將其保存在內存中不是問題。但在做foreach時,我正在使用LambdaExpression進行提取。這需要時間。 – Vikash

回答

0

問題&建議;

如果接收來自所述列表的數據 當SQL連接被反覆打開,僅需要一個請求到數據庫。您需要 列出該列表,如果它在此請求中有多處出現

結果:請求應該發送到數據庫一次。如果所有 列表都使用字典方法檢索,則可以實現15%的性能提升。如果您正在使用真正的大 數據時,可以異步工作

我們需要看到,隨着如果需要更詳細地得到啓動功能的內容。

+0

感謝您的建議。在我的第一種方法中,我使用了使用(SQLConnection con = new SQLConnection)從數據庫獲取記錄(請參閱編輯第一個方法代碼)。完成功能需要6分鐘,因爲我已經在PDF中產生了大約3500名員工。而就你的問題來說,功能的內容與使用iTextSharp.dll生成PDF相關。除上述兩種方法外,還有其他方法嗎? – Vikash

1

第二種方法涉及更少的數據庫往返更好。但根據你的意見

即使我目前正在使用第二種方法,一次獲取數據並將其保存在內存中不是一個問題。但在做foreach時,我正在使用LambdaExpression進行提取。這需要時間。

看起來像您的處理部分正在使用大量低效的線性搜索。可以通過準備和使用基於快速哈希的查找數據結構來顯着改進。

在這種特殊情況下,你需要兩個dictionaries快速定位通過PK的員工和位置的PK,和兩個lookups快速定位員工按部門PK和地點由員工PK。

假設你的類模型是這樣的(你可以用實際的屬性名稱/類型修改):

class Department 
{ 
    public int Id { get; set; } // PK 
    // Other properties... 
} 

class Employee 
{ 
    public int Id { get; set; } // PK 
    // Other properties... 
} 

class Location 
{ 
    public int Id { get; set; } // PK 
    // Other properties... 
} 

class EmployeeDepartment 
{ 
    public int EmployeeId { get; set; } // FK 
    public int DepartmentId { get; set; } // FK 
} 

class EmployeeLocation 
{ 
    public int EmployeeId { get; set; } // FK 
    public int LocationId { get; set; } // FK 
} 

然後,處理可能是這樣的:

//Fetch all necessary data 
List<Department> departmentList = sp.GetAllDeparments();  
List<Employee> employeeList = sp.GetAllEmployees(); 
List<Location> locationList = sp.GetAllLocations(); 
List<EmployeeLocation> employeeLocationList = sp.GetAllEmployeeLocations(); 
List<EmployeeDepartment> employeeDepartmentList = sp.GetAllEmployeeDepartments(); 

// Build the helper fast lookup structures 
var employeeById = employeeList.ToDictionary(e => e.Id); 
var locationById = locationList.ToDictionary(e => e.Id); 
var employeesByDepartmentId = employeeDepartmentList.ToLookup(e => e.DepartmentId, e => employeeById[e.EmployeeId]); 
var locationsByEmployeeId = employeeLocationList.ToLookup(e => e.EmployeeId, e => locationById[e.LocationId]); 

// The processing 
foreach (Department deparment in departmentList) 
{ 
    foreach (Employee employee in employeesByDepartmentId[deparment.Id]) 
    { 
     foreach (Location location in locationsByEmployeeId[employee.Id]) 
     { 

     } 
    } 
}