Is it possible to have a non clustered index on a field of a owned type? I have a value object that is being used in multiple entities and in one of them I want to create a index in one of the fields.
Mapped using the following implementation https://github.com/aspnet/EntityFrameworkCore/issues/15681#issuecomment-537789913
public class TaxesPercentage : ValueObject
{
public int Value { get; private set; }
public decimal Multiplier { get; private set; }
//โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ
public TaxesPercentage(int value)
{
Value = value >= 0 && value <= 100 ? value : throw new ArgumentOutOfRangeException($"{nameof(Value)} must be between 0 and 100.");
Multiplier = 1 + value / 100;
}
//โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ
protected override IEnumerable<object> GetAtomicValues()
{
yield return Value;
yield return Multiplier;
}
//โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ
public override string ToString() => $"{Value}";
}
Configuration:
public class PercentageConfiguration<TEntity> : IOwnedNavigationConfiguration<TEntity, TaxesPercentage>
where TEntity : class
{
public void Configure(OwnedNavigationBuilder<TEntity, TaxesPercentage> percentageConfiguration)
{
percentageConfiguration.Property(v => v.Value)
.HasColumnName("Percentage")
.IsRequired();
percentageConfiguration.Property(v => v.Multiplier)
.HasColumnType("decimal(3,2)")
.HasColumnName(nameof(TaxesPercentage.Multiplier))
.HasComputedColumnSql("(CONVERT([decimal](3,2),CONVERT([decimal](3,0),[Percentage])/(100.00)+(1))) PERSISTED");
}
}
Main entity configuration
class IvaEntityConfiguration : AuditableEntityTypeConfiguration<Iva>
{
public override void Configure(EntityTypeBuilder<Iva> ivaConfiguration)
{
//...
ivaConfiguration.ApplyOwnsOneConfiguration(i => i.Percentage, new PercentageConfiguration<Iva>());
//โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Indexes โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
ivaConfiguration.HasIndex(l => l.Percentage.Value)
.IsClustered(false)
.HasName("IX_Iva_Percentage")
.IsUnique();
//โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
base.Configure(ivaConfiguration);
}
}
Error:
The properties expression 'l => Convert(l.Percentage.Value, Object)' is not valid. The expression should represent a simple property access: 't => t.MyProperty'. When specifying multiple properties use an anonymous type: 't => new { t.MyProperty1, t.MyProperty2 }'. (Parameter 'propertyAccessExpression')
Stack trace
at Microsoft.EntityFrameworkCore.Infrastructure.ExpressionExtensions.GetPropertyAccessList(LambdaExpression propertyAccessExpression)
at Microsoft.EntityFrameworkCore.Metadata.Builders.EntityTypeBuilder`1.HasIndex(Expression`1 indexExpression)
at Catalog.Persistence.Configurations.Taxes.IvaEntityConfiguration.Configure(EntityTypeBuilder`1 ivaConfiguration) in C:\Users\AdrianoEscalante\source\repos\adminbeta\Catalog.Persistence\Configurations\Taxes\IvaEntityConfiguration.cs:line 30
at Microsoft.EntityFrameworkCore.ModelBuilder.ApplyConfiguration[TEntity](IEntityTypeConfiguration`1 configuration)
EF Core 3.1
Since index is on the property of the owned entity, it should be defined on owned entity too.
Try this
C#
percentageConfiguration.HasIndex(l => l.Value)
.IsClustered(false)
.HasName("IX_Iva_Percentage")
.IsUnique();
The problem is this index is specific to this table, no other table that uses this owned type will have it.
In that case you need to get the reference to owned type again.
C#
ivaConfiguration.OwnsOne(i => i.Percentage).HasIndex(l => l.Value)
.IsClustered(false)
.HasName("IX_Iva_Percentage")
.IsUnique();
It gives the same error.

Probably the problem lies with the way the extension method works.
@abcdma - There are few points to remember here
PercentageConfiguration applies configuration of all Percentage owned entities. If you want to configure the index on specific owned entity only then either you need to create a another derived configuration and apply that where applicable or configure index in the configuration of owner (IvaEntityConfiguration in this case)Thank you, was in a hurry and didn't even noticed that I forgot to change the extension method to the OwnsOne. It's working now.