I liked the answer of @StephenD. But I would do some improvements.
In your answer you need to add '?' on the PropertyInfo. In case there are no custom attributes that will result in null.
var attr = prop.PropertyInfo?.GetCustomAttribute<IndexAttribute>();
I searched the solution for more than one 'Index' attributes on the property. For each entity, group all indexes by names and get all the properties that corresponds to the appropriate index (in my case System.ComponentModel.DataAnnotations.Schema.IndexAttribute).
After that add all indexes to the entity.
public class User
{
[Index("IX_UserIdAndNickname", 1, IsUnique = false)]
public int UserId { get; set; }
[Index("IX_UserIdAndNickname", 2, IsUnique = false)]
[Index(IsUnique = true)]
public string Nickname { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
foreach (var entity in modelBuilder.Model.GetEntityTypes())
{
var indexeNameToAttribute = new Dictionary<string, System.ComponentModel.DataAnnotations.Schema.IndexAttribute>();
var indexNameToProperties = new Dictionary<string, List<IMutableProperty>>();
foreach (var prop in entity.GetProperties())
{
var attributes = prop.PropertyInfo?.GetCustomAttributes<System.ComponentModel.DataAnnotations.Schema.IndexAttribute>();
if (attributes != null && attributes.Count() > 0)
{
foreach (var attr in attributes)
{
// Index can be without name, so we add our convention
var indexName = attr.Name ?? $"IX_{prop.Name}";
if(!indexeNameToAttribute.ContainsKey(indexName))
{
indexeNameToAttribute.Add(indexName, attr);
}
if (!indexNameToProperties.ContainsKey(indexName))
{
indexNameToProperties.Add(indexName, new List<IMutableProperty>());
}
indexNameToProperties[indexName].Add(prop);
}
}
}
foreach (var prop in indexNameToProperties)
{
var addedIndex = entity.AddIndex(prop.Value, prop.Key);
var indexAttribute = indexeNameToAttribute[prop.Key];
addedIndex.IsUnique = indexAttribute.IsUnique;
}
}
}
}