我正在使用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