首页 > 解决方案 > 如何在 LINQ 中使用 Projection 将实体转换为 DTO 类

问题描述

我有 Linq 脚本,我想使用投影类来获取 DTO 类型的数据。我得到了 lambda expersion 的示例,但在 LINQ 脚本上出现错误。

林克脚本:

public class EziTransactionDto
{
   ... other properties

 public static Expression<Func<EziTransactionEntity, EziTransactionDto>> Projection()
    {
        return eziTransactionDto => new EziTransactionDto
        {
            EziTransactionId = eziTransactionDto.Id,
            LoginSiteID = eziTransactionDto.LoginSiteID,
            WorkCodes = eziTransactionDto.WorkCodes
        };

    }

LINQ查询:

  var ts = (from transaction in _eziTransactionRepository.GetAll<EziTransactionEntity>()
                  where transaction.LoginErrorCode != 0
                  select transaction
                 ).Select(EziTransactionDto.Projection);

错误:

在此处输入图像描述

标签: c#.netlinqentity-framework-projection

解决方案


在第一个 Select 之后,您的 IQueryable 已经将数据提取到本地进程,并使其成为 IEnumerable。

您可以在 Select 语句中进行此转换:

var eziTransactionDtos = _eziTransactionRepository.EziTransactionEntities
    .Where(eziTransactionEntity => eziTransationEntity.LoginErrorCode != 0)
    .Select(eziTransactionEntity => new EziTransactionDto
    {
        EziTransactionId = eziTransactionDto.Id,
        LoginSiteID = eziTransactionDto.LoginSiteID,
        WorkCodes = eziTransactionDto.WorkCodes,
    });

但是,如果您需要在多个地方将 EziTransactionEntities 转换为 EziTransactionDtos,那么为IQueryable<EziTransactionEntities>.

如果您不熟悉扩展方法,请参阅扩展方法揭秘

public static IQueryable<EziTransactionDto> ToEziTransactionDto(
    this IQueryable<EziTransactionEntity> eziTransactionEntities)
{
    return eziTransactionEntities.Select(eziTransactionEntity => new EziTransactionDto
    {
        EziTransactionId = eziTransactionDto.Id,
        LoginSiteID = eziTransactionDto.LoginSiteID,
        WorkCodes = eziTransactionDto.WorkCodes,
    });

用法:

var eziTransactionDtos = eziTransactionRepository.EziTransactionEntities
    .Where(eziTransactionEntity => eziTransationEntity.LoginErrorCode != 0)
    .ToEziTransactionDtos();

可重复使用的:

var transactionWithoutWorkCodes = eziTransactionRepository.EziTransactionEntities
    .Where(eziTransactionEntity => eziTransationEntity.WorkCode == null)
    .ToEziTransactionDtos();

易于单元测试:

List<EziTransactionEntity> testItems = ...
List<EziTransactionDto> expectedResults = ...

var testResults = testItems.AsQueryable().ToEziTransactionDtos();
Assert.AreQual(expectedResults, testResults, unorderedTransactionsComparer);

易于维护:如果您添加/删除/更改此转换的一个属性,您只需在一个位置执行此操作


推荐阅读