如您所见,我使用
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());
}
claims.OrderBy(string.IsNullOrWhiteSpace(input.Sorting) ? "DateOfServiceStart" : input.Sorting).PageBy(input);
抛出错误,因为它需要是
IQueryable
才能执行排序:
严重性代码描述项目文件行抑制状态 错误 CS1929“IEnumerable”不包含 “OrderBy”的定义和最佳扩展方法重载 'DynamicQueryableExtensions.OrderBy(IQueryable, 字符串, 参数 object?[])' 需要类型为 'System.Linq.IQueryable' 的接收器
所以,我担心这个查询的性能问题,因为我们在使用时具体化了查询,然后再次将其移至AsQueryable,在使用的方法中,我们再次将其转换为列表,如何才能我改进这段代码?另外,如果我不像这样应用 GetClaimList 方法中的
.ToList()
.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)=>新的透明标识符ClaimTransactionSetBatch( 外层 = 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()的原因)
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
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
};