Linq到Sql:优化lamba表达式-清理代码

本文关键字:代码 表达式 lamba Sql 优化 Linq | 更新日期: 2023-09-27 18:00:26

我有一个表达式,它生成对数据库的单个查询:

db = new MyDataContext();
var productInCity = db.Products
                         .Where(n => n.id == 2)
                         .Select(k => new ProductInCityDto()
                         {
                              ProductName = k.ProductName,
                              CityName = k.Store.City.Name,
                              CountryName = k.Store.City.Country.Name
                              .
                              .
                              . 
                         })
                         .FirstOrDefault();

我想通过将映射放在函数、扩展方法或对象的构造函数中,使代码更干净,比如

db = new MyDataContext();
var productInCity = db.Products
                        .Where(n => n.id == 2)
                        .Select(k => new ProductInCityDto(k))
                        .FirstOrDefault();

但是,在这种情况下,会生成对数据库的多个查询(我使用LinqToSqlProfiler)。

有没有一种方法可以隔离映射(Select语句)以实现更好的代码可读性?

Linq到Sql:优化lamba表达式-清理代码

YES,如果您查看IQueryable上Select扩展方法的实际签名,您会发现它不接受函数,而是接受Expression>。

所以,就这么做吧。。。

Expression<Func<Product, ProductInCityDto>> MyMappingExpression
{
    get
    {
        return product => new ProductInCityDto
        {
            ...
        }
    }
}

然后

db = new MyDataContext();
            var productInCity = db.Products.Where(n => n.id == 2)
                .Select(MyMappingExpression)
            .FirstOrDefault();

若您需要在这个过程中使用MyMappingExpression,您可能需要将其转换为

Func<Product, ProductInCityDto> 

通过调用Expression.Compile()方法。

您可以使用AutoMapper,而不是手动创建映射。但是,如果您不想使用第三方工具创建映射,只需将查询更改为以下内容即可;

var productInCity = new ProductInCity(
                   db.Products.Include("Store").SingleOrDefault(n => n.id == 2));