【问题标题】:Is it possible to pass select as an expression in order to make projection DbSet?是否可以将 select 作为表达式传递以进行投影 DbSet?
【发布时间】:2019-11-14 05:14:31
【问题描述】:

我想查询一个数据库表。我想知道是否可以通过将表达式传递给 DbSet 来使用投影。

这是我的查询:

 var gameBankResultVM = await (context.GameBanks
                .Where(l => l.referenceId == confirm.referenceId)
                .Select(g => new GameBankConfirmResponseVM()
                {
                    referenceId = g.referenceId,
                    paymentId = null,
                    productCode = g.productCode,
                    quantity = g.quantity,
                    deliveredQuantity = g.quantity,
                    currency = g.currency,
                    version = g.version,
                    signature = g.signature,
                    ApplicationCode = g.ApplicationCode,
                    productDescription = g.productDescription,
                    unitPrice = g.unitPrice,
                    totalPrice = g.totalPrice,
                    totalPayablePrice = g.totalPrice,
                    coupons = g.coupons.Select(c => new GameCouponBankVM()
                    {
                        Pin = c.Pin,
                        Serial = c.Serial,
                        expiryDate = c.expiryDate
                    }).ToList()
                })).ToListAsync();

这就是我想要的;

public virtual async Task<List<TEntity>> GetGamesProjectionAsync(
            Expression<Func<TEntity, bool>> where, Expression<Func<TEntity, bool>> select)
        {
            return await dbSet.Where(where).Select(select).ToListAsync();
        }

并根据我的查询投影调用此方法:

//Query GameBank database
                var gameBankResult =
                    await _unitOfWork.GameBankRepository.GetGamesAsync(g =>
                        g.productCode == requestDto.productCode && g.referenceId == null, t => ...);

【问题讨论】:

  • Select方法的签名,需要传入正确的东西...
  • 你可以传入一个列的字符串(由分隔符分隔,如','),但这不是类型安全的方式
  • Expression&lt;Func&lt;TEntity, List&lt;TEntity&gt;&gt;&gt; ?
  • 不,更像这个:Select&lt;TSource, TResult&gt;(this IQueryable&lt;TSource&gt; source, Expression&lt;Func&lt;TSource, TResult&gt;&gt; selector)。请注意,Select 方法不必返回您的实体,它可以是 DTO、int 或完全不同的东西。
  • Select 的签名是Select&lt;TSource,TResult&gt;() 这意味着调用代码应该知道源实体和结果实体。因此,该方法也可以利用仅提供IQueryable&lt;TSource&gt; 的方法,并在其自身的主体中应用 Select 而不是跳过箍将其作为参数传递。我的意思是,它并没有改进任何封装,那么有什么好处呢?

标签: c# asp.net-web-api async-await entity-framework-6


【解决方案1】:

我只是省略了选择(投影)部分,并为通用存储库实现了一个方法,如下所示:

public virtual async Task<List<TEntity>> GetGamesAsync(
        Expression<Func<TEntity, bool>> where)
    {
        return await dbSet.Where(where).ToListAsync();
    }

我在我的业务服务层调用它:

//Query GameBank database
            var gameBankResult =
                await _unitOfWork.GameBankRepository.GetGamesAsync(g =>
                    g.productCode == requestDto.productCode && g.referenceId == null);

这是我的问题的解决方案,我使用 Automapper 进行转换。

    var config = new MapperConfiguration(cfg =>
                {

                    cfg.CreateMap<GameBank, GameConfirmResponse>();
                    cfg.CreateMap<GameBankPin, Coupon>();
                });
                var iMapper = config.CreateMapper();
var gameBankConfirmResponse = iMapper.Map<IList<GameBank>, IList<GameConfirmResponse>>(gameBankConfirmResult);

现在我只需要使用 Unity 来整理周围的所有映射 :) 希望有人帮助我。

我肯定需要类似下面的东西:

grouping to generic method in Repository EF C#

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-30
    • 1970-01-01
    • 2011-02-28
    • 2013-01-16
    • 1970-01-01
    • 1970-01-01
    • 2019-05-21
    相关资源
    最近更新 更多