Use GetCustomAttributes to find the attributes, and LINQ to filter and get an anonymous object which holds the Property and the Attribute.
Use PropertyInfo.GetValue to read the actual value.
But please beware that the reflection calls are pretty expensive:
var propertiesWithAttribute = typeof(Entity).GetProperties()
// use projection to get properties with their attributes -
.Select(pi => new { Property = pi, Attribute = pi.GetCustomAttributes(typeof(MyAttribute), true).FirstOrDefault() as MyAttribute})
// filter only properties with attributes
.Where(x => x.Attribute != null)
.ToList();
foreach (Entity entity in collection)
{
foreach (var pa in propertiesWithAttribute)
{
object value = pa.Property.GetValue(entity, null);
Console.WriteLine($"PropertyName: {pa.Property.Name}, PropertyValue: {value}, AttributeName: {pa.Attribute.GetType().Name}");
}
}