2012-04-18 71 views
2

我正在尝试使用Dapper进行数据访问(在ASP.NET MVC3 FWIW中)。我有一个T-SQL视图(在SQL Server中)是这样的:使用Dapper从T-SQL视图填充对象

SELECT s.*, c.CompanyId AS BreakPoint c.Name AS CompanyName 
FROM tblStaff AS s 
INNER JOIN tblCompanies AS c ON c.CompanyId = s.CompanyId 

非常简单。基本上是一个员工名单,每个员工都有一个公司。

我遇到的问题是,我试图将此查询的输出映射到我的POCO上,但因为视图中的每个字段必须是唯一的(即公司名称而不是已存在于tblStaff中的名称)映射到POCO不起作用。

下面的代码:

var sql = @"select * from qryStaff"; 
var people = _db.Query<Person, Company, Person>(sql, (person, company) => {person.Company = company; return person;}, splitOn: "BreakPoint"); 

任何意见,我怎么可能会解决这个难题?我愿意改变我的观点,因为现在我很难理解如何进步。

回答

0

您应该明确列出从您返回的所有字段(无星号!)以及字段名称不唯一的位置,请使用别名进行重复数据删除。作为例子:

SELECT 
    s.ComapnyName as CompanyName1, 
    s.BreakPoint as BreakPoint1, 
    ... 
    c.CompanyId AS BreakPoint, 
    c.Name AS CompanyName 
FROM tblStaff AS s 
INNER JOIN tblCompanies AS c ON c.CompanyId = s.CompanyId 

列出的字段和您可能使用的别名当然取决于您的代码。通常,您可以调整查询中的别名以匹配POCO的属性名称。

另外,作为一般的经验法则,最好远离SQL查询中的通配符,因为这样的问题被引入。 Here's a decent article关于SQL查询最佳实践。

摘录:

使用您的 代码中的SELECT语句列的显式名称具有许多优点。首先,SQL Server仅返回您的应用程序需要的数据,而不是您的应用程序不会使用的一堆附加数据 。通过仅返回 需要的数据,您可以优化SQL Server需要执行的工作量,以便收集所需的所有信息列。此外,通过不使用 星号(*)命名法,您还可以最小化向您的应用程序发送与您的SELECT语句相关联的数据 所需的网络流量(字节数)的数量 。

而且通过明确的命名你的专栏,你是绝缘的相关的一些数据库 模式改变可能发生在你 SELECT语句引用任何表中潜在的故障 您的应用程序。如果您要使用星号(*)命名法,并且有人需要在表中添加新列,那么即使没有 ,您的应用程序也会开始接收这些额外数据列的数据,即使没有 更改您的应用程序代码。如果您的应用程序期望 只有特定数量的列要返回,那么只要有人向您的 引用表中的一个添加了附加列,就会失败 。因此,即使有人在SELECT语句中引用的任何一个 表中添加了新列,通过在您的 SELECT语句中明确命名列,您的应用程序总是会得到相同数量的 列返回的列。

+0

我得到的问题是,我的公司模型有一个名为'Name'而不是CompanyName的属性,但为了在视图中维护一个唯一的列,我必须使用别名,因此精巧器映射可以'将视图列映射到POCO属性。没有将我的模型属性重命名为荒谬的名称,有没有解决方案? – 2012-04-24 15:52:44

+0

您可以运行两个单独的查询来填充业务对象。我不确定你有另外的选择。 – 2012-04-24 16:19:26