I want to put an index on multiple columns (like stated in this question), but one of the properties is a navigation property without a foreign key property in the model.
TL;DR at the bottom.
My model:
public class User
{
public int Id { get; set; }
public string Email { get; set; }
public virtual Shop Shop { get; set; }
}
public class Shop
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Context : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Shop> Shops { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().HasRequired(u => u.Shop).WithMany();
modelBuilder.Entity<User>().Property(u => u.Email).HasMaxLength(256);
}
}
I use an extension (based on the for mentioned question):
internal static class ModelBuilderExtensions
{
public static StringPropertyConfiguration AddMultiColumnIndex(this StringPropertyConfiguration config, string indexName, int columnOrder, bool unique = false, bool clustered = false)
{
var indexAttribute = new IndexAttribute(indexName, columnOrder) { IsUnique = unique, IsClustered = clustered };
var indexAnnotation = new IndexAnnotation(indexAttribute);
return config.HasColumnAnnotation(IndexAnnotation.AnnotationName, indexAnnotation);
}
public static PrimitivePropertyConfiguration AddMultiColumnIndex(this PrimitivePropertyConfiguration property, string indexName, int columnOrder, bool unique = false, bool clustered = false)
{
var indexAttribute = new IndexAttribute(indexName, columnOrder) { IsUnique = unique, IsClustered = clustered };
var indexAnnotation = new IndexAnnotation(indexAttribute);
return property.HasColumnAnnotation(IndexAnnotation.AnnotationName, indexAnnotation);
}
}
I wish to create an index as follows:
modelBuilder.Entity<User>().Property(x => x.Email).AddMultiColumnIndex("UX_User_EmailShopId", 0, unique: true);
modelBuilder.Entity<User>().Property(x => x.Shop.Id).AddMultiColumnIndex("UX_User_EmailShopId", 1, unique: true);
But this gives me an error when scaffolding a migration:
System.InvalidOperationException: The type 'Shop' has already been configured as an entity type. It cannot be reconfigured as a complex type.
When I try to add the index as follows it gives another error:
modelBuilder.Entity<User>().Property(x => x.Shop).AddMultiColumnIndex("UX_User_EmailShopId", 1, unique: true);
The type 'My.NameSpace.Shop' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Data.Entity.ModelConfiguration.Configuration.StructuralTypeConfiguration.Property(System.Linq.Expressions.Expression>)
TL;DR
So my question is, how do I add an index using the fluent-api on the email and shop (id) combination when the shop_id is not defined in my model (and I don't want to define it)?
The resultant SQL should look something like:
CREATE UNIQUE NONCLUSTERED INDEX [UX_User_EmailShopId] ON [dbo].[User]
(
[Email] ASC,
[Shop_Id] ASC
)