feat(Migrations): SQL Server Filterable indexes.#6866
feat(Migrations): SQL Server Filterable indexes.#6866AndriySvyryd merged 1 commit intodotnet:feature/1.2.0from
Conversation
| public virtual string Name { get; [param: NotNull] set; } | ||
| public virtual ICollection<IndexColumnModel> IndexColumns { get; [param: NotNull] set; } = new List<IndexColumnModel>(); | ||
| public virtual bool IsUnique { get; [param: NotNull] set; } | ||
| public virtual string WhereClauses { get; set; } |
There was a problem hiding this comment.
Any reason this is plural? Am not familiar with SQL Server here but in PostgreSQL it's just a standard single WHERE clause
There was a problem hiding this comment.
This should be renamed in Filter. Just forgot this entry.
| [CanBeNull] string schema = null, | ||
| bool unique = false) | ||
| bool unique = false, | ||
| string filter = null) |
| [CanBeNull] string schema = null, | ||
| bool unique = false) | ||
| bool unique = false, | ||
| string filter = null) |
|
|
||
| /// <summary> | ||
| /// Gets the properties that this index is defined on. | ||
| /// </summary> |
There was a problem hiding this comment.
Filtered indexes are a SQL Server feature, so it should be stored as an annotation using extension methods. See how .IsClustered is implemented.
There was a problem hiding this comment.
On a second though, other relational providers support it so it can go in .Relational
| Sql); | ||
| } | ||
|
|
||
| public override void CreateIndexOperation_with_whrere_clauses() |
| IsUnique = false | ||
| }); | ||
|
|
||
| [Fact] |
| Name = "IX_People_Name", | ||
| Table = "People", | ||
| Columns = new[] { "Name" }, | ||
| IsUnique = false, |
There was a problem hiding this comment.
This is SQLServer-specific SQL in a provider-independent test. However, it's not terribly important as this is only a unit test (i.e. the SQL never gets sent/evaluated), so no real harm.
| Sql); | ||
| } | ||
|
|
||
| [Fact] |
There was a problem hiding this comment.
Shouldn't this test simply override CreateIndexOperation_with_where_clauses, defined in MigrationSqlGeneratorTestBase.cs?
| Sql); | ||
| } | ||
|
|
||
| [Fact] |
There was a problem hiding this comment.
Should probably be defined in MigrationSqlGeneratorTestBase.cs and overridden here (useful for other providers)
434cfc6 to
548c9a9
Compare
|
@AndriySvyryd please review latest check-in. I moved it into relational annotation but not completely sure that this proper way to use realational attributes (i tried to mimic |
AndriySvyryd
left a comment
There was a problem hiding this comment.
You also need to add a method to RelationalIndexBuilderAnnotations so filters can be set by conventions, as well as in SqlServerIndexBuilderAnnotations that would allow to set a filter just for SQL Server in case multiple providers are used with the same model.
| /// <summary> | ||
| /// Gets a value indicating whre clauses to specific index. | ||
| /// </summary> | ||
| string Filter { get; set; } |
There was a problem hiding this comment.
The properties on this interface should be read-only.
Also the fix typos in the comment or just remove it.
| && s.Properties.Select(diffContext.FindTarget).SequenceEqual(t.Properties), | ||
| // ReSharper disable once ImplicitlyCapturedClosure | ||
| (s, t) => s.IsUnique == t.IsUnique | ||
| && s.Relational().Filter == t.Relational().Filter |
There was a problem hiding this comment.
You need to use Annotations.For(t).Filter in all of the migrations code, this allows it to read the provider-specific value
| Table = Annotations.For(index.DeclaringEntityType).TableName, | ||
| Columns = index.Properties.Select(p => Annotations.For(p).ColumnName).ToArray() | ||
| Columns = index.Properties.Select(p => Annotations.For(p).ColumnName).ToArray(), | ||
| Filter = index.Relational().Filter |
|
@AndriySvyryd done. Please review |
| <ProjectReference Include="..\..\src\Microsoft.EntityFrameworkCore.Relational\Microsoft.EntityFrameworkCore.Relational.csproj"> | ||
| <Project>{6A25DF99-2615-46D8-9532-821764647EE1}</Project> | ||
| <Name>Microsoft.EntityFrameworkCore.Relational</Name> | ||
| </ProjectReference> |
There was a problem hiding this comment.
This project shouldn't reference .Relational
|
|
||
|
|
||
| [Fact] | ||
| public void Can_write_index_builder_extension_with_where_clauses() |
There was a problem hiding this comment.
Move this to RelationalBuilderExtensionsTest and add a similar test to RelationalMetadataExtensionsTest
|
General question about this PR: currently by default we add the filter |
|
@divega Sure, I can do it after this is merged |
| Annotations.For(t).Name, | ||
| StringComparison.OrdinalIgnoreCase) | ||
| && s.IsUnique == t.IsUnique | ||
| && Annotations.For(s).Filter == Annotations.For(t).Filter |
There was a problem hiding this comment.
@AndriySvyryd May be HasDifferences can handle this comparing? It looks like i can remove this lines
There was a problem hiding this comment.
HasDifferences diffs migrations annotations, while they have the same API they are different from model annotations, the added conditions are still needed.
|
@AndriySvyryd done, please review |
AndriySvyryd
left a comment
There was a problem hiding this comment.
Almost there.
After making the change below rebase again on the latest feature/1.2.0 and squash the commits
| Annotations.For(t).Name, | ||
| StringComparison.OrdinalIgnoreCase) | ||
| && s.IsUnique == t.IsUnique | ||
| && Annotations.For(s).Filter == Annotations.For(t).Filter |
There was a problem hiding this comment.
HasDifferences diffs migrations annotations, while they have the same API they are different from model annotations, the added conditions are still needed.
| /// <summary> | ||
| /// Gets a value indicating whre clauses to specific index. | ||
| /// </summary> | ||
| public string Filter |
There was a problem hiding this comment.
This needs to be virtual. Also correct spelling in the comment or just remove it.
|
|
||
| if (Index.Relational().Filter != null) | ||
| { | ||
| lines.Add("." + nameof(RelationalIndexBuilderExtensions.HasFilter) + "(\"" + Index.Relational().Filter + "\")"); |
| /// </summary> | ||
| public new virtual bool Name([CanBeNull] string value) => SetName(value); | ||
|
|
||
| /// <summary> |
| protected abstract IMigrationsSqlGenerator SqlGenerator { get; } | ||
|
|
||
| protected virtual string Sql { get; set; } | ||
| [Fact] |
f5d5866 to
2e0498a
Compare
|
@AndriySvyryd @roji done, please review. |
|
LGTM |
|
Thank you for your contribution. |
Please check if the PR fulfills these requirements
Please review the guidelines for CONTRIBUTING.md for more details.
Fixed #5817