public override async IAsyncEnumerable <Path> ComputePaths(EvaluationContext ctx) { _entityPaths ??= EntityCandidate.ComputePaths(ctx); await foreach (var path in _entityPaths) { yield return(path.Append(PropertyName)); // <-- Best guess, since we don't know if the property is simple or nav } }
public override async IAsyncEnumerable <Path> ComputeSelect(EvaluationContext ctx) { await foreach (var select in EntityCandidate.ComputeSelect(ctx)) { yield return(select); } _entityPaths ??= EntityCandidate.ComputePaths(ctx); await foreach (var path in _entityPaths) { yield return(path.Append(PropertyName)); } }
public override async Task <object> Evaluate(EvaluationContext ctx) { var entityCandidate = await EntityCandidate.Evaluate(ctx); if (entityCandidate == null) { // Template property access implements null propagation out of the box return(null); } if (entityCandidate is Entity entity) { if (entity is EntityWithKey entityWithKey && PropertyName == "Id") { return(entityWithKey.GetId()); } var entityType = entity.GetType(); var propInfo = entityType.GetProperty(PropertyName); if (propInfo == null || propInfo.GetCustomAttribute <NotMappedAttribute>() != null) { throw new TemplateException($"Property '{PropertyName}' does not exist on type {entityType.Name}."); } else if (!entity.EntityMetadata.TryGetValue(PropertyName, out FieldMetadata meta)) { // Developer mistake throw new InvalidOperationException($"Property '{PropertyName}' on type {entityType.Name} was not loaded correctly."); } else if (meta == FieldMetadata.Restricted) { throw new TemplateException($"Your account is not granted access to property '{PropertyName}' on type '{entityType.Name}'."); } else if (meta == FieldMetadata.Loaded) { return(propInfo.GetValue(entity)); } else { // For future proofing throw new InvalidOperationException($"Unknown FieldMetadata value '{meta}'."); } } else { throw new TemplateException($"Property access '.{PropertyName}' is only valid on model entities."); } }