我有这个 linq 查询: 私有异步任务

问题描述 投票:0回答:1

如您所见,我使用

FirstOrDefault()
 从分组数据中检索第一个元素,确保高效的数据检索,而无需进行不必要的枚举。

但是我需要归还它

AsQueryable()
因为在另一种方法中我有:

public async Task<PagedResultDto<ClaimSummaryDto>> GetListAsync(GetClaimListDto input) { var claimTransactionSetBatch = await this.GetClaimList(input); var claims = claimTransactionSetBatch.Select(x => new ClaimSummaryDto() { AgencyIdentifier = x.Claim.AgencyIdentifier, .... } claims = claims.OrderBy(string.IsNullOrWhiteSpace(input.Sorting) ? "DateOfServiceStart" : input.Sorting).PageBy(input); return new PagedResultDto<ClaimSummaryDto>(total, claims.ToList()); }

因此,返回一个 IQueryable,如果我将其作为列表返回,则代码:

claims.OrderBy(string.IsNullOrWhiteSpace(input.Sorting) ? "DateOfServiceStart" : input.Sorting).PageBy(input);

抛出错误,因为它需要是

IQueryable
 才能执行排序:

严重性代码描述项目文件行抑制状态
错误 CS1929“IEnumerable”不包含
“OrderBy”的定义和最佳扩展方法重载
'DynamicQueryableExtensions.OrderBy(IQueryable, 字符串, 参数
object?[])' 需要类型为 'System.Linq.IQueryable' 的接收器

所以,我担心这个查询的性能问题,因为我们在使用

.ToList()

时具体化了查询,然后再次将其移至AsQueryable,在使用的方法中,我们再次将其转换为列表,如何才能我改进这段代码?另外,如果我不像这样应用 GetClaimList 方法中的
.ToList()

...

              {
                  Batch = grouped.Select(x => x.claimBatch).FirstOrDefault(),
                  TransactionSet = grouped.Select(x => x.transactionSet).FirstOrDefault(),
                  Claim = grouped.Select(x => x.claim).FirstOrDefault()
              });


return claims;
当它试图最后实现查询时,它会抛出一个大错误:

return new PagedResultDto<ClaimSummaryDto>(total, claims.ToList());

错误:

LINQ 表达式 'DbSet()
.Where(c => __ef_filter__p_0 || (Guid?)EF.Property(c, "TenantId") == __ef_filter__CurrentTenantId_1)
.SelectMany(
集合选择器:c => DbSet()
.Where(c0 => EF.Property

(c, "Id") != null && object.Equals( objA: (对象)EF.Property

(c, "Id"), objB: (对象)EF.Property
(c0, "ClaimBatchId"))) .DefaultIfEmpty(), 结果选择器:(c,c)=>新的透明标识符

( 外层 = c, 内=c )) .SelectMany( 集合选择器: ti => DbSet() .Where(c1 => EF.Property(ti.Inner, "Id") != null && object.Equals( objA: (对象)EF.Property(ti.Inner, "Id"), objB: (对象)EF.Property(c1, "TransactionSetId"))) .DefaultIfEmpty(), 结果选择器:(ti,c)=>新的透明标识符,ClaimTransactionSetClaim>( 外=ti, 内=c )) 。加入( 内部:DbSet() .Where(c2 => __ef_filter__p_0 || (Guid?)EF.Property(c2, "TenantId") == __ef_filter__CurrentTenantId_1), 外键选择器: ti0 => (对象)ti0.Inner.ClaimId, innerKeySelector: c2 => (object)c2.Id, 结果选择器:(ti0,c2)=>新的透明标识符,ClaimTransactionSetClaim>,Claim>( 外层 = ti0, 内=c2 )) .Where(ti1 => ti1.Outer.Outer.Outer.SourceClaimBatchId == null && True && True && False || __input_Status_1 .包含(ti1.Inner.Status) && True && True && True && True) .OrderByDescending(ti1 => ti1.Outer.Outer.Outer.Id) .GroupBy(ti1 => ti1.Inner.Id) .Select(g => 新的 ClaimTransactionSetBatch{ 批次 = g .AsQueryable() .Select(e0 => e0.Outer.Outer.Outer) .FirstOrDefault(), 交易集 = g .AsQueryable() .Select(e0 => e0.Outer.Outer.Inner) .FirstOrDefault(), 索赔= g .AsQueryable() .Select(e0 => 包含表达式( 实体表达式: 包含表达式( 实体表达式: 包含表达式( 实体表达式: 包含表达式( 实体表达式: e0.内部, 导航表达式: MaterializeCollectionNavigation( 导航:Claim.ServiceLines, 子查询:DbSet() .Where(c3 => EF.Property(e0.Inner, "Id") != null && object.Equals( objA: (对象)EF.Property(e0.Inner, "Id"), objB: (对象)EF.Property(c3, "ClaimId")))), ServiceLines) , 导航表达式: MaterializeCollectionNavigation( 导航:Claim.CustomProperties, 子查询:DbSet() .Where(c4 => EF.Property(e0.Inner, "Id") != null && object.Equals( objA: (对象)EF.Property(e0.Inner, "Id"), objB:(对象)EF.Property(c4,“ClaimId”)))),CustomProperties) , 导航表达式: MaterializeCollectionNavigation( 导航:Claim.TransactionSets, 子查询:DbSet() .Where(c5 => EF.Property(e0.Inner, "Id") != null && object.Equals( objA: (对象)EF.Property(e0.Inner, "Id"), objB:(对象)EF.Property(c5,“ClaimId”)))),TransactionSets) , 导航表达式: MaterializeCollectionNavigation( 导航:Claim.EventHistory, 子查询:DbSet() .Where(c6 => __ef_filter__p_0 || (Guid?)EF.Property(c6, "TenantId") == __ef_filter__CurrentTenantId_1) .Where(c6 => EF.Property(e0.Inner, "Id") != null && object.Equals( objA: (对象)EF.Property(e0.Inner, "Id"), objB:(对象)EF.Property(c6,“ClaimId”)))),EventHistory) ) .FirstOrDefault() } ) .OrderBy(e1 => e1.Claim.ServiceLines .Select(x => x.DateOfServiceStart) .Where(日期 => 日期.HasValue) .Min())' 无法翻译。要么以可翻译的形式重写查询,要么切换到客户端评估 通过插入对 'AsEnumerable'、'AsAsyncEnumerable' 的调用显式地 “ToList”或“ToListAsync”。看 https://go.microsoft.com/fwlink/?linkid=2101038了解更多信息。 我认为这是因为需要首先具体化firstOrDefault()(这就是我使用.ToList()的原因)

课程:

ClaimTransactionSetBatch

internal class ClaimTransactionSetBatch { public Claim Claim { get; set; } public ClaimTransactionSet TransactionSet { get; set; } public ClaimBatch Batch { get; set; } }

索赔:

public class Claim : AuditedAggregateRoot<Guid>, IMultiTenant, IProcessibleType { private IList<ClaimEvent> _eventHistory; public IList<ClaimEvent> EventHistory { get => this._eventHistory.OrderByDescending(e => e.TimeStamp).ToList(); set => _eventHistory = value; } private string _claimTypeCode; private decimal? _netPaidAmount; private ClaimPaymentStatus _paymentStatus; private ClaimVisitMatchStatus _visitMatchStatus; private ClaimStatus _status; private IList<ClaimAction> _claimActions; public IList<ClaimAction> AvailableActions { get { ... } } public Guid? TenantId { get; set; } public string SubmitterIdentifier { get; set; } public string ReceiverIdentifier { get; set; } public ClaimPaymentStatus PaymentStatus { get => this._paymentStatus; set { ... } } public string ClaimIdentifier { get; set; } public string BatchIdentifier { get; set; } // Include the rest of the properties here public string ClientGender { get; set; } public string ClientDiagnosisCode { get; set; } public Decimal NetAmount { get; set; } public string ClaimTypeCode { get => this._claimTypeCode; set { ... } } public ClaimType ClaimType { get; private set; } public string FacilityTypeCode { get; set; } public ClaimProcessingStatus ProcessingStatus { get; set; } public string ProcessingResultMessage { get; set; } public ClaimStatus Status { get => this._status; set { ... } } public Guid? ProcessingRulesetId { get; set; } public ClaimVisitMatchStatus VisitMatchStatus { get => this._visitMatchStatus; set { ... } } public decimal? NetPaidAmount { get => this._netPaidAmount; set { ... } } public DateTime? LastPaymentReceivedDate { get; set; } public string CostCenterIdentifier { get; set; } public string CostCenterCode { get; set; } public IList<ClaimServiceLine> ServiceLines { get; set; } public IList<ClaimCustomProperty> CustomProperties { get; set; } public IEnumerable<ClaimTransactionSetClaim> TransactionSets { get; private set; } public ClaimRulesetEntityType ClaimRulesetEntityType => ClaimRulesetEntityType.Claim; public Claim() { this.ServiceLines = new List<ClaimServiceLine>(); this.CustomProperties = new List<ClaimCustomProperty>(); this.EventHistory = new List<ClaimEvent>(); this._eventHistory = new List<ClaimEvent>(); this._claimActions = new List<ClaimAction>(); this._paymentStatus = ClaimPaymentStatus.PaymentPending; this._status = ClaimStatus.InProcess; } public Claim(Guid id) : base(id) { this.ServiceLines = new List<ClaimServiceLine>(); this.CustomProperties = new List<ClaimCustomProperty>(); this.EventHistory = new List<ClaimEvent>(); this._eventHistory = new List<ClaimEvent>(); this._claimActions = new List<ClaimAction>(); this._paymentStatus = ClaimPaymentStatus.PaymentPending; this._status = ClaimStatus.InProcess; } public Claim(Guid id, Guid claimTransactionSetId) : this(id) { //ClaimTransactionSetId = claimTransactionSetId; } }

索赔交易集

public class ClaimTransactionSet : Entity<Guid> { private IList<ClaimTransactionSetClaim> claims = new List<ClaimTransactionSetClaim>(); private DateTime? transmissionStatusChangedDate; private TransmissionStatus transmissionStatus; public Guid ClaimBatchId { get; set; } public Guid? SourceClaimTransactionSetId { get; set; } public IEnumerable<ClaimTransactionSetClaim> Claims => this.claims; public string GroupControlNumber { get; set; } public string GroupSenderCode { get; set; } public string GroupReceiverCode { get; set; } public string TransactionSetControlNumber { get; set; } public TransmissionStatus TransmissionStatus { get => this.transmissionStatus; set { if (this.transmissionStatus != value) { this.transmissionStatus = value; this.transmissionStatusChangedDate = DateTime.UtcNow; } } } public DateTime? TransmissionStatusChangedDate => this.transmissionStatusChangedDate; }

索赔批次:

public class ClaimBatch : AuditedAggregateRoot<Guid>, IMultiTenant, IProcessibleType { public Guid? TenantId { get; set; } public Guid? SourceClaimBatchId { get; set; } public string InterchangeControlNumber { get; set; } public string BatchIdentifier { get; set; } public DateTime? BatchDate { get; set; } public string SenderIdentifier { get; set; } public string ReceiverIdentifier { get; set; } public string AgencyIdentifier { get; set; } public DateTime ReceivedDate { get; set; } public string Filename { get; set; } public ClaimBatchProcessingMethod ProcessingMethod { get; set; } public ClaimProcessingStatus ProcessingStatus { get; set; } public string ProcessingResultMessage { get; set; } public Guid? ProcessingRulesetId { get; set; } public IList<ClaimTransactionSet> TransactionSets { get; set; } public IList<ClaimBatchEvent> EventHistory { get; set; } }

这个查询应该是transletabke。最好根据您的需求更正
OrderBy
c# performance linq entity-framework-core
1个回答
0
投票

var claimBatchQry = ... // initialize as IQueryable created from DbSet var claims = from claimBatch in claimBatchQry from transactionSet in claimBatch.TransactionSets .OrderBy(x => x.Id) .Take(1) .DefaultIfEmpty() from transactionSetClaim in transactionSet.Claims .OrderBy(x => x.Id) .Take(1) .DefaultIfEmpty() where ... orderby claimBatch.Id descending select new ClaimTransactionSetBatch { Batch = claimBatch, TransactionSet = transactionSet, Claim = transactionSetClaim.Claim // or just transactionSetClaim };

    

© www.soinside.com 2019 - 2024. All rights reserved.