我有一个带有 Select 的 lambda 表达式,其中创建了一个新的 ResourcesResponse.Resource 对象。 Resource 对象有一个计算出的 Order 字段,该字段调用名为 GetResourceTypeOrder 的异步存储库方法,所有内容如下所示:
ResourcesResponse instantiation:
var tmp = new ResourcesResponse
{
Cost = aux.Sum(s => s.Cost),
Resources = aux
.OrderBy(k => k.Order)
.ThenBy(k => k.TypeId)
.Select(async s => new ResourcesResponse.Resource
{
Id = ((ulong)s.Id).ToString(),
Charge = s.Charge,
Cost = s.Cost,
CurrencyCode = s.CurrencyCode,
ForecastCharge = s.ForecastCharge,
ForecastCost = s.ForecastCost,
ForecastUsedUnits = s.ForecastUsedUnits,
ParentId = ((ulong?)s.ParentId).ToString(),
Order = await _resourcesRepository.GetResourceTypeOrder(s.TypeId),
Rate = s.Rate,
TypeId = s.TypeId,
UsedUnits = s.UsedUnits,
})
.ToArray(),
Id = ((ulong)entry.Id).ToString(),
Name = entry.Name,
Description = entry.Description,
OriginalId = entry.OriginalId,
ResourceTypeId = entry.ResourceTypeId,
ResourceType = await _resourcesRepository.GetResourceTypeName(entry.ResourceTypeId),
Order = await _resourcesRepository.GetResourceTypeOrder(entry.ResourceTypeId),
State = entry.State,
Zone = entry.Zone,
Charge = aux.Sum(s => s.Charge),
};
ResourceResponse:
public class ResourcesResponse
{
public string Id { get; set; } = default!;
public string Name { get; set; } = default!;
public string? Description { get; set; } = default!;
public string OriginalId { get; set; } = default!;
public string ResourceType { get; set; } = default!;
[JsonIgnore]
public int? Order { get; set; } = default!;
public ResourceTypeValues ResourceTypeId { get; set; }
public string? CurrencyCode => Resources?.FirstOrDefault()?.CurrencyCode;
public decimal? Charge { get; set; }
public decimal Cost { get; set; }
public decimal? ForecastCharge { get; set; }
public decimal? ForecastCost { get; set; }
public string Zone { get; set; } = default!;
public string State { get; set; } = default!;
public Resource[] Resources { get; set; } = default!;
public sealed class Resource
{
[JsonIgnore]
public string Id { get; set; } = default!;
[JsonIgnore]
public string? ParentId { get; set; } = default!;
[JsonIgnore]
public int? Order { get; set; } = default!;
public string CurrencyCode { get; set; } = default!;
public decimal Rate { get; set; }
public long UsedUnits { get; set; }
public decimal Cost { get; set; }
public decimal? Charge { get; set; }
public long? ForecastUsedUnits { get; set; }
public decimal? ForecastCost { get; set; }
public decimal? ForecastCharge { get; set; }
public string Type { get; set; } = default!;
public ResourceTypeValues TypeId { get; set; }
public string? Unit { get; set; } = default!;
public bool? Hourly { get; set; } = default!;
}
}
ResourceTypeOrder:
public async Task<int?> GetResourceTypeOrder(ResourceTypeValues resourceTypeId)
{
ICache.Operation<int?> myTableCacheImplementation = async delegate (string key)
{
var dic = await _repositoryResourceTypes.FindAll().ToDictionaryAsync(k => k.Id);
return dic[resourceTypeId].Order;
};
return await _vdcCache.GetOrCreateAsync(ResourceTypeCacheKey.ResourceTypeOrder, myTableCacheImplementation, null);
}
我的问题是我不知道在哪里放置缺少的 await (或者编译器接受整个表达式所需的任何内容)。
对于父级 ResourceResponse 还有一个计算的 Order 字段,但正如您所看到的,它是正确的。
很明显,我可以在 GetResourceTypeOrder 的末尾添加 .Result 并删除异步运算符,但这不是 async / wait 的想法。
我自己回答:
处理此问题的方法(以 @Fildor 注释为起点)是重构 GetResourceTypeOrder 方法,使其返回 完整的字典,而不是特定元素。然后,我只需在创建 ResourcesResponse 实例之前检索字典,并获取并将相应的 Order 分配给“Order”字段,即 resourceTypes[s.TypeId].Order:
var resourceTypes = await _resourcesRepository.GetResourceTypes();
var tmp = new ResourcesResponse
{
Cost = aux.Sum(s => s.Cost),
Resources = aux
.OrderBy(k => k.Order)
.ThenBy(k => k.TypeId)
.Select(s => new ResourcesResponse.Resource
{
Id = ((ulong)s.Id).ToString(),
Charge = s.Charge,
Cost = s.Cost,
CurrencyCode = s.CurrencyCode,
ForecastCharge = s.ForecastCharge,
ForecastCost = s.ForecastCost,
ForecastUsedUnits = s.ForecastUsedUnits,
ParentId = ((ulong?)s.ParentId).ToString(),
Order = resourceTypes[s.TypeId].Order,
Rate = s.Rate,
TypeId = s.TypeId,
UsedUnits = s.UsedUnits,
}).ToArray(),
Id = ((ulong)entry.Id).ToString(),
Name = entry.Name,
Description = entry.Description,
OriginalId = entry.OriginalId,
ResourceTypeId = entry.ResourceTypeId,
ResourceType = await _resourcesRepository.GetResourceTypeName(entry.ResourceTypeId),
Order = await _resourcesRepository.GetResourceTypeOrder(entry.ResourceTypeId),
State = entry.State,
Zone = entry.Zone,
Charge = aux.Sum(s => s.Charge),
};