我正在使用ASP.net中的依賴注入開發我的第一個數據驅動域。如何高效地填充數據訪問層模型?
在我的數據訪問層,如果創造了一些領域的數據模型,例如:
public class Company {
public Guid CompanyId { get; set; }
public string Name { get; set; }
}
public class Employee {
public Guid EmployeeId { get; set; }
public Guid CompanyId { get; set; }
public string Name { get; set; }
}
我已經再開發的接口,如:
public interface ICompanyService {
IEnumerable<Model.Company> GetCompanies();
IEnumerable<Model.Employee> GetEmployees();
IEnumerable<Model.Employee> GetEmployees(Guid companyId);
}
在一個單獨的模塊,我已經實現這個接口使用Linq到Sql:
public class CompanyService : ICompanyService {
public IEnumerable<Model.Employee> GetEmployees();
{
return EmployeeDb
.OrderBy(e => e.Name)
.Select(e => e.ToDomainEntity())
.AsEnumerable();
}
}
WhereDoDomainEntity()被實現在員工信息庫類的擴展方法基礎機構類:
public Model.EmployeeToDomainEntity()
{
return new Model.Employee {
EmployeeId = this.EmployeeId,
CompanyId = this.CompanyId,
Name = this.Name
};
}
對於這一點,我有或多或少的遵循了模式,如馬克西曼的優秀圖書「在.NET依賴注入」中描述 - 和所有的作品都很好。
我卻想延長我的基本款也包括關鍵的參考模型,因此域Employee類將成爲:
public class Employee {
public Guid EmployeeId { get; set; }
public Guid CompanyId { get; set; }
public Company { get; set; }
public string Name { get; set; }
}
和ToDomainEntity()函數將擴大到:
public Model.Employee ToDomainEntity()
{
return new Model.Employee {
EmployeeId = this.EmployeeId,
CompanyId = this.CompanyId,
Company = (this.Company == null) ? null : this.Company.ToDomainEntity()
Name = this.Name
};
}
我懷疑從領域建模的角度來看這可能是'不好的做法',但我認爲,如果我要開發一個特定的視圖模型來達到相同的目的,我也會遇到這個問題。
實質上,我遇到的問題是填充數據模型的速度/效率。如果我使用上述的ToDomainEntity()方法,Linq to Sql會創建一個單獨的SQL調用來檢索每個員工公司記錄的數據。正如您所期望的那樣,這會大大增加評估SQL表達式所花費的時間(從我們的測試數據庫大約100ms到7秒),特別是如果數據樹很複雜(因爲單獨的SQL調用是爲了填充每個節點/樹的子節點)。
如果我創建數據模型「內聯......
public IEnumerable<Model.Employee> GetEmployees();
{
return EmployeeDb
.OrderBy(e => e.Name)
.Select(e => new Model.Employee {
EmployeeId = e.EmployeeId,
/* Other field mappings */
Company = new Model.Company {
CompanyId = e.Company.CompanyId,
/* Other field mappings */
}
}).AsEnumerable();
}
LINQ to SQL的產生本身使用了一個漂亮的,緊密的SQL語句‘內連接’的方法,以本公司與員工聯繫起來。
我有兩個問題:
1)它認爲「不好的做法」從一個域類對象中引用相關數據類?
2)如果是這種情況,並且爲此目的創建了特定的視圖模型,那麼使用填充模型的正確方法是什麼,而不必訴諸創建內聯分配塊來構建表達式樹?
任何幫助/建議將不勝感激。
如果您開始開發,最好選擇實體框架(而不是LINQ to SQL),因爲Microsoft將來會繼續開發實體框架。 – Steven 2012-07-12 10:16:44
一些額外的研究表明,這裏的底層問題是Linq(n + 1)問題 - 在StackOverflow中很好地介紹了這個問題。到目前爲止,我還沒有看到在代碼中解決這個問題的好方法 - 除了創建特定的視圖模型(我希望避免)。我確實發現了一篇文章,建議使用表達式構建可能是答案,但我找不到任何可能如何開發這種方法的例子。 – Neilski 2012-07-12 19:44:10