Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use the generic IndexBuilder. #20524

Merged
merged 1 commit into from
Apr 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions src/EFCore/Metadata/Builders/EntityTypeBuilder`.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ public virtual KeyBuilder<TEntity> HasKey([NotNull] Expression<Func<TEntity, obj

/// <summary>
/// Creates an alternate key in the model for this entity type if one does not already exist over the specified
/// properties. This will force the properties to be read-only. Use <see cref="HasIndex" /> to specify uniqueness
/// properties. This will force the properties to be read-only. Use <see cref="HasIndex(string[])" /> or
/// <see cref="HasIndex(Expression{Func{TEntity, object}})" /> to specify uniqueness
/// in the model that does not force properties to be read-only.
/// </summary>
/// <param name="keyExpression">
Expand All @@ -124,7 +125,8 @@ public virtual KeyBuilder<TEntity> HasAlternateKey([NotNull] Expression<Func<TEn

/// <summary>
/// Creates an alternate key in the model for this entity type if one does not already exist over the specified
/// properties. This will force the properties to be read-only. Use <see cref="HasIndex" /> to specify uniqueness
/// properties. This will force the properties to be read-only. Use <see cref="HasIndex(string[])" /> or
/// <see cref="HasIndex(Expression{Func{TEntity, object}})" /> to specify uniqueness
/// in the model that does not force properties to be read-only.
/// </summary>
/// <param name="propertyNames"> The names of the properties that make up the key. </param>
Expand Down Expand Up @@ -234,6 +236,18 @@ public virtual IndexBuilder<TEntity> HasIndex([NotNull] Expression<Func<TEntity,
Check.NotNull(indexExpression, nameof(indexExpression)).GetPropertyAccessList(),
ConfigurationSource.Explicit).Metadata);

/// <summary>
/// Configures an index on the specified properties. If there is an existing index on the given
/// set of properties, then the existing index will be returned for configuration.
/// </summary>
/// <param name="propertyNames"> The names of the properties that make up the index. </param>
/// <returns> An object that can be used to configure the index. </returns>
public new virtual IndexBuilder<TEntity> HasIndex([NotNull] params string[] propertyNames)
=> new IndexBuilder<TEntity>(
Builder.HasIndex(
Check.NotEmpty(propertyNames, nameof(propertyNames)),
ConfigurationSource.Explicit).Metadata);

/// <summary>
/// <para>
/// Configures a relationship where the target entity is owned by (or part of) this entity.
Expand Down
15 changes: 13 additions & 2 deletions src/EFCore/Metadata/Builders/OwnedNavigationBuilder`.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,23 @@ public virtual OwnedNavigationBuilder<TEntity, TDependentEntity> Ignore(
/// </para>
/// </param>
/// <returns> An object that can be used to configure the index. </returns>
public virtual IndexBuilder HasIndex([NotNull] Expression<Func<TDependentEntity, object>> indexExpression)
=> new IndexBuilder(
public virtual IndexBuilder<TEntity> HasIndex([NotNull] Expression<Func<TDependentEntity, object>> indexExpression)
=> new IndexBuilder<TEntity>(
DependentEntityType.Builder.HasIndex(
Check.NotNull(indexExpression, nameof(indexExpression)).GetPropertyAccessList(), ConfigurationSource.Explicit)
.Metadata);

/// <summary>
/// Configures an index on the specified properties. If there is an existing index on the given
/// set of properties, then the existing index will be returned for configuration.
/// </summary>
/// <param name="propertyNames"> The names of the properties that make up the index. </param>
/// <returns> An object that can be used to configure the index. </returns>
public new virtual IndexBuilder<TEntity> HasIndex([NotNull] params string[] propertyNames)
=> new IndexBuilder<TEntity>(
DependentEntityType.Builder.HasIndex(
Check.NotEmpty(propertyNames, nameof(propertyNames)), ConfigurationSource.Explicit).Metadata);

/// <summary>
/// <para>
/// Configures the relationship to the owner.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,19 +231,35 @@ public static ModelBuilderTest.TestReferenceCollectionBuilder<TEntity, TRelatedE
return builder;
}

public static ModelBuilderTest.TestIndexBuilder HasFilter(
this ModelBuilderTest.TestIndexBuilder builder, string filterExpression)
public static ModelBuilderTest.TestIndexBuilder<TEntity> HasFilter<TEntity>(
this ModelBuilderTest.TestIndexBuilder<TEntity> builder, string filterExpression)
{
var indexBuilder = builder.GetInfrastructure();
indexBuilder.HasFilter(filterExpression);
switch (builder)
{
case IInfrastructure<IndexBuilder<TEntity>> genericBuilder:
genericBuilder.Instance.HasFilter(filterExpression);
break;
case IInfrastructure<IndexBuilder> nongenericBuilder:
nongenericBuilder.Instance.HasFilter(filterExpression);
break;
}

return builder;
}

public static ModelBuilderTest.TestIndexBuilder HasName(
this ModelBuilderTest.TestIndexBuilder builder, string name)
public static ModelBuilderTest.TestIndexBuilder<TEntity> HasName<TEntity>(
this ModelBuilderTest.TestIndexBuilder<TEntity> builder, string name)
{
var indexBuilder = builder.GetInfrastructure();
indexBuilder.HasName(name);
switch (builder)
{
case IInfrastructure<KeyBuilder<TEntity>> genericBuilder:
genericBuilder.Instance.HasName(name);
break;
case IInfrastructure<KeyBuilder> nongenericBuilder:
nongenericBuilder.Instance.HasName(name);
break;
}

return builder;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,19 @@ namespace Microsoft.EntityFrameworkCore.ModelBuilding
{
public static class SqlServerTestModelBuilderExtensions
{
public static ModelBuilderTest.TestIndexBuilder IsClustered(
this ModelBuilderTest.TestIndexBuilder builder, bool clustered = true)
public static ModelBuilderTest.TestIndexBuilder<TEntity> IsClustered<TEntity>(
this ModelBuilderTest.TestIndexBuilder<TEntity> builder, bool clustered = true)
{
var indexBuilder = builder.GetInfrastructure();
indexBuilder.IsClustered(clustered);
switch (builder)
{
case IInfrastructure<IndexBuilder<TEntity>> genericBuilder:
genericBuilder.Instance.IsClustered(clustered);
break;
case IInfrastructure<IndexBuilder> nongenericBuilder:
nongenericBuilder.Instance.IsClustered(clustered);
break;
}

return builder;
}

Expand Down
35 changes: 27 additions & 8 deletions test/EFCore.Tests/ModelBuilding/ModelBuilderGenericTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,11 @@ public override TestEntityTypeBuilder<TEntity> Ignore(Expression<Func<TEntity, o
public override TestEntityTypeBuilder<TEntity> Ignore(string propertyName)
=> Wrap(EntityTypeBuilder.Ignore(propertyName));

public override TestIndexBuilder HasIndex(Expression<Func<TEntity, object>> indexExpression)
=> new TestIndexBuilder(EntityTypeBuilder.HasIndex(indexExpression));
public override TestIndexBuilder<TEntity> HasIndex(Expression<Func<TEntity, object>> indexExpression)
=> new GenericTestIndexBuilder<TEntity>(EntityTypeBuilder.HasIndex(indexExpression));

public override TestIndexBuilder HasIndex(params string[] propertyNames)
=> new TestIndexBuilder(EntityTypeBuilder.HasIndex(propertyNames));
public override TestIndexBuilder<TEntity> HasIndex(params string[] propertyNames)
=> new GenericTestIndexBuilder<TEntity>(EntityTypeBuilder.HasIndex(propertyNames));

public override TestOwnedNavigationBuilder<TEntity, TRelatedEntity> OwnsOne<TRelatedEntity>(string navigationName)
=> new GenericTestOwnedNavigationBuilder<TEntity, TRelatedEntity>(EntityTypeBuilder.OwnsOne<TRelatedEntity>(navigationName));
Expand Down Expand Up @@ -458,6 +458,25 @@ public override TestKeyBuilder<TEntity> HasAnnotation(string annotation, object
KeyBuilder<TEntity> IInfrastructure<KeyBuilder<TEntity>>.Instance => KeyBuilder;
}

public class GenericTestIndexBuilder<TEntity> : TestIndexBuilder<TEntity>, IInfrastructure<IndexBuilder<TEntity>>
{
public GenericTestIndexBuilder(IndexBuilder<TEntity> indexBuilder)
{
IndexBuilder = indexBuilder;
}

private IndexBuilder<TEntity> IndexBuilder { get; }
public override IMutableIndex Metadata => IndexBuilder.Metadata;

public override TestIndexBuilder<TEntity> HasAnnotation(string annotation, object value)
=> new GenericTestIndexBuilder<TEntity>(IndexBuilder.HasAnnotation(annotation, value));

public override TestIndexBuilder<TEntity> IsUnique(bool isUnique = true)
=> new GenericTestIndexBuilder<TEntity>(IndexBuilder.IsUnique(isUnique));

IndexBuilder<TEntity> IInfrastructure<IndexBuilder<TEntity>>.Instance => IndexBuilder;
}

protected class GenericTestNavigationBuilder : TestNavigationBuilder
{
public GenericTestNavigationBuilder(NavigationBuilder navigationBuilder)
Expand Down Expand Up @@ -759,11 +778,11 @@ public override TestOwnedNavigationBuilder<TEntity, TDependentEntity> Ignore(
Expression<Func<TDependentEntity, object>> propertyExpression)
=> Wrap(OwnedNavigationBuilder.Ignore(propertyExpression));

public override TestIndexBuilder HasIndex(params string[] propertyNames)
=> new TestIndexBuilder(OwnedNavigationBuilder.HasIndex(propertyNames));
public override TestIndexBuilder<TEntity> HasIndex(params string[] propertyNames)
=> new GenericTestIndexBuilder<TEntity>(OwnedNavigationBuilder.HasIndex(propertyNames));

public override TestIndexBuilder HasIndex(Expression<Func<TDependentEntity, object>> indexExpression)
=> new TestIndexBuilder(OwnedNavigationBuilder.HasIndex(indexExpression));
public override TestIndexBuilder<TEntity> HasIndex(Expression<Func<TDependentEntity, object>> indexExpression)
=> new GenericTestIndexBuilder<TEntity>(OwnedNavigationBuilder.HasIndex(indexExpression));

public override TestOwnershipBuilder<TEntity, TDependentEntity> WithOwner(string ownerReference)
=> new GenericTestOwnershipBuilder<TEntity, TDependentEntity>(
Expand Down
35 changes: 27 additions & 8 deletions test/EFCore.Tests/ModelBuilding/ModelBuilderNonGenericTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,12 @@ public override TestEntityTypeBuilder<TEntity> Ignore(Expression<Func<TEntity, o
public override TestEntityTypeBuilder<TEntity> Ignore(string propertyName)
=> Wrap(EntityTypeBuilder.Ignore(propertyName));

public override TestIndexBuilder HasIndex(Expression<Func<TEntity, object>> indexExpression)
=> new TestIndexBuilder(
public override TestIndexBuilder<TEntity> HasIndex(Expression<Func<TEntity, object>> indexExpression)
=> new NonGenericTestIndexBuilder<TEntity>(
EntityTypeBuilder.HasIndex(indexExpression.GetPropertyAccessList().Select(p => p.GetSimpleMemberName()).ToArray()));

public override TestIndexBuilder HasIndex(params string[] propertyNames)
=> new TestIndexBuilder(EntityTypeBuilder.HasIndex(propertyNames));
public override TestIndexBuilder<TEntity> HasIndex(params string[] propertyNames)
=> new NonGenericTestIndexBuilder<TEntity>(EntityTypeBuilder.HasIndex(propertyNames));

public override TestOwnedNavigationBuilder<TEntity, TRelatedEntity> OwnsOne<TRelatedEntity>(string navigationName)
=> new NonGenericTestOwnedNavigationBuilder<TEntity, TRelatedEntity>(
Expand Down Expand Up @@ -446,6 +446,25 @@ public override TestKeyBuilder<TEntity> HasAnnotation(string annotation, object
KeyBuilder IInfrastructure<KeyBuilder>.Instance => KeyBuilder;
}

public class NonGenericTestIndexBuilder<TEntity> : TestIndexBuilder<TEntity>, IInfrastructure<IndexBuilder>
{
public NonGenericTestIndexBuilder(IndexBuilder indexBuilder)
{
IndexBuilder = indexBuilder;
}

private IndexBuilder IndexBuilder { get; }
public override IMutableIndex Metadata => IndexBuilder.Metadata;

public override TestIndexBuilder<TEntity> HasAnnotation(string annotation, object value)
=> new NonGenericTestIndexBuilder<TEntity>(IndexBuilder.HasAnnotation(annotation, value));

public override TestIndexBuilder<TEntity> IsUnique(bool isUnique = true)
=> new NonGenericTestIndexBuilder<TEntity>(IndexBuilder.IsUnique(isUnique));

IndexBuilder IInfrastructure<IndexBuilder>.Instance => IndexBuilder;
}

protected class
NonGenericTestReferenceNavigationBuilder<TEntity, TRelatedEntity> : TestReferenceNavigationBuilder<TEntity, TRelatedEntity>
where TEntity : class
Expand Down Expand Up @@ -754,11 +773,11 @@ public override TestOwnedNavigationBuilder<TEntity, TDependentEntity> Ignore(
=> Wrap<TEntity, TDependentEntity>(
OwnedNavigationBuilder.Ignore(propertyExpression.GetPropertyAccess().GetSimpleMemberName()));

public override TestIndexBuilder HasIndex(params string[] propertyNames)
=> new TestIndexBuilder(OwnedNavigationBuilder.HasIndex(propertyNames));
public override TestIndexBuilder<TEntity> HasIndex(params string[] propertyNames)
=> new NonGenericTestIndexBuilder<TEntity>(OwnedNavigationBuilder.HasIndex(propertyNames));

public override TestIndexBuilder HasIndex(Expression<Func<TDependentEntity, object>> indexExpression)
=> new TestIndexBuilder(
public override TestIndexBuilder<TEntity> HasIndex(Expression<Func<TDependentEntity, object>> indexExpression)
=> new NonGenericTestIndexBuilder<TEntity>(
OwnedNavigationBuilder.HasIndex(
indexExpression.GetPropertyAccessList().Select(p => p.GetSimpleMemberName()).ToArray()));

Expand Down
27 changes: 8 additions & 19 deletions test/EFCore.Tests/ModelBuilding/ModelBuilderTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,8 @@ public abstract TestEntityTypeBuilder<TEntity> Ignore(

public abstract TestEntityTypeBuilder<TEntity> Ignore(string propertyName);

public abstract TestIndexBuilder HasIndex(Expression<Func<TEntity, object>> indexExpression);
public abstract TestIndexBuilder HasIndex(params string[] propertyNames);
public abstract TestIndexBuilder<TEntity> HasIndex(Expression<Func<TEntity, object>> indexExpression);
public abstract TestIndexBuilder<TEntity> HasIndex(params string[] propertyNames);

public abstract TestOwnedNavigationBuilder<TEntity, TRelatedEntity> OwnsOne<TRelatedEntity>(string navigationName)
where TRelatedEntity : class;
Expand Down Expand Up @@ -301,23 +301,12 @@ public abstract class TestKeyBuilder<TEntity>
public abstract TestKeyBuilder<TEntity> HasAnnotation(string annotation, object value);
}

public class TestIndexBuilder : IInfrastructure<IndexBuilder>
public abstract class TestIndexBuilder<TEntity>
{
public TestIndexBuilder(IndexBuilder indexBuilder)
{
IndexBuilder = indexBuilder;
}

private IndexBuilder IndexBuilder { get; }
public IMutableIndex Metadata => IndexBuilder.Metadata;

public virtual TestIndexBuilder HasAnnotation(string annotation, object value)
=> new TestIndexBuilder(IndexBuilder.HasAnnotation(annotation, value));

public virtual TestIndexBuilder IsUnique(bool isUnique = true)
=> new TestIndexBuilder(IndexBuilder.IsUnique(isUnique));
public abstract IMutableIndex Metadata { get; }

IndexBuilder IInfrastructure<IndexBuilder>.Instance => IndexBuilder;
public abstract TestIndexBuilder<TEntity> HasAnnotation(string annotation, object value);
public abstract TestIndexBuilder<TEntity> IsUnique(bool isUnique = true);
}

public abstract class TestPropertyBuilder<TProperty>
Expand Down Expand Up @@ -517,8 +506,8 @@ public abstract TestNavigationBuilder Navigation<TNavigation>(
public abstract TestOwnedNavigationBuilder<TEntity, TDependentEntity> Ignore(
Expression<Func<TDependentEntity, object>> propertyExpression);

public abstract TestIndexBuilder HasIndex(params string[] propertyNames);
public abstract TestIndexBuilder HasIndex(Expression<Func<TDependentEntity, object>> indexExpression);
public abstract TestIndexBuilder<TEntity> HasIndex(params string[] propertyNames);
public abstract TestIndexBuilder<TEntity> HasIndex(Expression<Func<TDependentEntity, object>> indexExpression);

public abstract TestOwnershipBuilder<TEntity, TDependentEntity> WithOwner(string ownerReference);
public abstract TestOwnershipBuilder<TEntity, TDependentEntity> WithOwner(
Expand Down