2013-01-16 27 views
1

我有一个问题,并想知道是否有办法让我的蛋糕,吃它。LINQ到SQL表达式树执行区问题

目前我有一个存储库和查询样式模式,我如何使用Linq2Sql,但是我有一个问题,我看不到一个很好的方法来解决它。这是问题的一个例子:

var someDataMapper = new SomeDataMapper(); 
var someDataQuery = new GetSomeDataQuery(); 
var results = SomeRepository.HybridQuery(someDataQuery) 
          .Where(x => x.SomeColumn == 1 || x.SomeColumn == 2) 
          .OrderByDescending(x => x.SomeOtherColumn) 
          .Select(x => someDataMapper.Map(x)); 

return results.Where(x => x.SomeMappedColumn == "SomeType"); 

主要位要注意这里的映射,查询,信息库,然后最后的where子句。我正在做这个更大的重构的一部分,我们发现有很多类似的查询获得稍微不同的结果集,但随后将它们以相同的方式映射到特定于域的模型。例如,取回一个tbl_car,然后将其映射到一个Car对象。因此,一个映射器基本上采用同一类型和吐出另一个,所以完全一样的东西通常会在选择发生:

// Non mapped version 
select(x => new Car 
{ 
    Id = x.Id, 
    Name = x.Name, 
    Owner = x.FirstName + x.Surname 
}); 

// Mapped version 
select(x => carMapper.Map(x)); 

让车子映射器是在其上做返回相同的类似查询各个领域更可重用最终的结果,但沿途做了不同的比赛。然而,我不断收到错误说Map不能转换为SQL,这是我不希望它是好的,但我明白,因为它是在表达式树中它会尝试将其转换。

{"Method 'SomeData Map(SomeTable)' has no supported translation to SQL."} 

最后被返回并映射被进一步向上传递堆栈其他对象使用,这使得使用LINQ到SQL的组合物的能力,以添加其他条件到查询然后最后ToList()或itterate对象在返回的数据,但他们过滤器的基础上映射的模式,而不是原来的表的模式,我相信这是完全正常的,如以前回答过的问题:

Linq2Sql point of retrieving data

所以总结起来,可我如图所示使用我的映射模式,而不尝试将单个部分转换为SQL?

回答

5

是的,你可以。最后Select之前把AsEnumerable():但是

var results = SomeRepository.HybridQuery(someDataQuery) 
          .Where(x => x.SomeColumn == 1 || x.SomeColumn == 2) 
          .OrderByDescending(x => x.SomeOtherColumn) 
          .AsEnumerable() 
          .Select(x => someDataMapper.Map(x)); 

,请注意,第二Where - 上SomeMappedColumn操作一个 - 现在将内存而不是由数据库执行。如果最后的where子句显着减少结果集,这可能是一个问题。


另一种方法是创建一个方法,该方法返回该映射的表达式树。只要映射中发生的所有事情都可以转换为SQL,下面的内容应该可以工作。

Expression<Func<EntityType, Car>> GetCarMappingExpression() 
{ 
    return new Expression<Func<EntityType, Car>>(x => new Car 
    { 
     Id = x.Id, 
     Name = x.Name, 
     Owner = x.FirstName + x.Surname 
    }); 
} 

用法是这样的:

var results = SomeRepository.HybridQuery(someDataQuery) 
          .Where(x => x.SomeColumn == 1 || x.SomeColumn == 2) 
          .OrderByDescending(x => x.SomeOtherColumn) 
          .Select(GetCarMappingExpression()); 
+0

是的,不幸的是一些基本的查询可能会拉回来成千上万的记录,随后在差异服务不同的方式过滤进一步下降,所以他们可能会从10000走在实际评估时仅为20。因此,如果可能的话,我不想尽早提取数据。 – Grofit

+0

@Grofit:请参阅更新。 –

+0

已经用表达式树路由了,谢谢! – Grofit