Linq to Sql:优化lambda表达式 - 干净的代码

时间:2013-02-22 09:17:49

标签: c# asp.net linq

我有这个表达式,它为数据库生成单个查询:

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();

但是,在这种情况下,会生成对DB的多个查询(我使用LinqToSql Profiler)。

有没有办法隔离映射(Select语句)以获得更好的代码可读性?

2 个答案:

答案 0 :(得分:3)

是的,如果你看一下IQueryable上Select扩展方法的实际签名,你会发现它不是一个函数,而是一个表达式>。

所以,就这样做......

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()方法。

答案 1 :(得分:0)

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

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