3

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

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

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

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

4

2 回答 2

3

是的,如果您查看 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() 方法。

于 2013-02-22T09:24:07.450 回答
0

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

var productInCity = new ProductInCity(
                   db.Products.Include("Store").SingleOrDefault(n => n.id == 2));
于 2013-02-22T09:29:22.980 回答