├── .gitattributes ├── .gitignore ├── EntityFramework.IndexingExtensions ├── EntityFramework.IndexingExtensions.csproj ├── EntityFramework.IndexingExtensions.nuspec ├── EntityFramework.IndexingExtensions.sln ├── IndexOptions.cs ├── IndexingExtensions.cs ├── Properties │ └── AssemblyInfo.cs └── packages.config ├── LICENSE └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set default behaviour, in case users don't have core.autocrlf set. 2 | * text=auto 3 | 4 | #Generated geohash data files 5 | *.dat text eol=lf 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs) 2 | [Bb]in/ 3 | [Oo]bj/ 4 | 5 | # mstest test results 6 | TestResults 7 | 8 | ## Ignore Visual Studio temporary files, build results, and 9 | ## files generated by popular Visual Studio add-ons. 10 | 11 | # User-specific files 12 | *.suo 13 | *.user 14 | *.sln.docstates 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Rr]elease/ 19 | x64/ 20 | *_i.c 21 | *_p.c 22 | *.ilk 23 | *.meta 24 | *.obj 25 | *.pch 26 | *.pdb 27 | *.pgc 28 | *.pgd 29 | *.rsp 30 | *.sbr 31 | *.tlb 32 | *.tli 33 | *.tlh 34 | *.tmp 35 | *.log 36 | *.vspscc 37 | *.vssscc 38 | .builds 39 | 40 | # Visual C++ cache files 41 | ipch/ 42 | *.aps 43 | *.ncb 44 | *.opensdf 45 | *.sdf 46 | 47 | # Visual Studio profiler 48 | *.psess 49 | *.vsp 50 | *.vspx 51 | 52 | # Guidance Automation Toolkit 53 | *.gpState 54 | 55 | # ReSharper is a .NET coding add-in 56 | _ReSharper* 57 | 58 | # NCrunch 59 | *.ncrunch* 60 | .*crunch*.local.xml 61 | 62 | # Installshield output folder 63 | [Ee]xpress 64 | 65 | # DocProject is a documentation generator add-in 66 | DocProject/buildhelp/ 67 | DocProject/Help/*.HxT 68 | DocProject/Help/*.HxC 69 | DocProject/Help/*.hhc 70 | DocProject/Help/*.hhk 71 | DocProject/Help/*.hhp 72 | DocProject/Help/Html2 73 | DocProject/Help/html 74 | 75 | # Click-Once directory 76 | publish 77 | 78 | # Publish Web Output 79 | *.Publish.xml 80 | 81 | # NuGet Packages Directory 82 | packages 83 | 84 | # Windows Azure Build Output 85 | csx 86 | *.build.csdef 87 | 88 | # Windows Store app package directory 89 | AppPackages/ 90 | 91 | # Others 92 | [Bb]in 93 | [Oo]bj 94 | sql 95 | TestResults 96 | [Tt]est[Rr]esult* 97 | *.Cache 98 | ClientBin 99 | [Ss]tyle[Cc]op.* 100 | ~$* 101 | *.dbmdl 102 | Generated_Code #added for RIA/Silverlight projects 103 | 104 | # Backup & report files from converting an old project file to a newer 105 | # Visual Studio version. Backup files are not needed, because we have git ;-) 106 | _UpgradeReport_Files/ 107 | Backup*/ 108 | UpgradeLog*.XML 109 | -------------------------------------------------------------------------------- /EntityFramework.IndexingExtensions/EntityFramework.IndexingExtensions.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {1738F39A-0178-476E-B61E-BF108606D19B} 8 | Library 9 | Properties 10 | System.Data.Entity 11 | EntityFramework.IndexingExtensions 12 | v4.0 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | packages\EntityFramework.6.1.0\lib\net40\EntityFramework.dll 35 | 36 | 37 | packages\EntityFramework.6.1.0\lib\net40\EntityFramework.SqlServer.dll 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 60 | -------------------------------------------------------------------------------- /EntityFramework.IndexingExtensions/EntityFramework.IndexingExtensions.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | EntityFramework.IndexingExtensions 5 | $version$ 6 | Entity Framework Indexing Extensions 7 | $author$ 8 | $description$ 9 | en-US 10 | https://raw.githubusercontent.com/mj1856/TimeZoneNames/master/LICENSE 11 | https://github.com/mj1856/EntityFramework.IndexingExtensions 12 | false 13 | EF Entity Framework Indexing Indexes Index 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /EntityFramework.IndexingExtensions/EntityFramework.IndexingExtensions.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EntityFramework.IndexingExtensions", "EntityFramework.IndexingExtensions.csproj", "{1738F39A-0178-476E-B61E-BF108606D19B}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {1738F39A-0178-476E-B61E-BF108606D19B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {1738F39A-0178-476E-B61E-BF108606D19B}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {1738F39A-0178-476E-B61E-BF108606D19B}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {1738F39A-0178-476E-B61E-BF108606D19B}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /EntityFramework.IndexingExtensions/IndexOptions.cs: -------------------------------------------------------------------------------- 1 | namespace System.Data.Entity 2 | { 3 | /// 4 | /// Specifies options for an index. 5 | /// 6 | [Flags] 7 | public enum IndexOptions 8 | { 9 | /// 10 | /// A non-clustered index. 11 | /// 12 | Nonclustered = 0, 13 | 14 | /// 15 | /// A clustered index. 16 | /// 17 | Clustered = 1, 18 | 19 | /// 20 | /// A unique index. 21 | /// 22 | Unique = 2, 23 | 24 | /// 25 | /// A clustered, unique index. 26 | /// 27 | ClusteredUnique = Clustered | Unique 28 | } 29 | } -------------------------------------------------------------------------------- /EntityFramework.IndexingExtensions/IndexingExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel.DataAnnotations.Schema; 3 | using System.Data.Entity.Infrastructure.Annotations; 4 | using System.Data.Entity.ModelConfiguration; 5 | using System.Data.Entity.ModelConfiguration.Configuration; 6 | using System.Linq; 7 | using System.Reflection; 8 | 9 | namespace System.Data.Entity 10 | { 11 | public static class IndexingExtensions 12 | { 13 | /// 14 | /// Configures a non-clustered index for this entity type. 15 | /// 16 | /// The type of the entity. 17 | /// The entity type configuration. 18 | /// The name of the index. 19 | /// Selects the property to be indexed. 20 | /// Selects additional properties to be added to the index. 21 | /// The entity type configuration, for fluent chaining. 22 | public static EntityTypeConfiguration HasIndex( 23 | this EntityTypeConfiguration entityTypeConfiguration, 24 | string indexName, 25 | Func, PrimitivePropertyConfiguration> propertySelector, 26 | params Func, PrimitivePropertyConfiguration>[] additionalPropertySelectors) 27 | where TEntity : class 28 | { 29 | return entityTypeConfiguration.HasIndex(indexName, IndexOptions.Nonclustered, 30 | propertySelector, additionalPropertySelectors); 31 | } 32 | 33 | /// 34 | /// Configures an index for this entity type. 35 | /// 36 | /// The type of the entity. 37 | /// The entity type configuration. 38 | /// The name of the index. 39 | /// One or more options used when creating the index. 40 | /// Selects the property to be indexed. 41 | /// Selects additional properties to be added to the index. 42 | /// The entity type configuration, for fluent chaining. 43 | public static EntityTypeConfiguration HasIndex( 44 | this EntityTypeConfiguration entityTypeConfiguration, 45 | string indexName, IndexOptions indexOptions, 46 | Func, PrimitivePropertyConfiguration> propertySelector, 47 | params Func, PrimitivePropertyConfiguration>[] additionalPropertySelectors) 48 | where TEntity : class 49 | { 50 | AddIndexColumn(indexName, indexOptions, 1, propertySelector(entityTypeConfiguration)); 51 | for (int i = 0; i < additionalPropertySelectors.Length; i++) 52 | { 53 | AddIndexColumn(indexName, indexOptions, i + 2, additionalPropertySelectors[i](entityTypeConfiguration)); 54 | } 55 | 56 | return entityTypeConfiguration; 57 | } 58 | 59 | private static void AddIndexColumn( 60 | string indexName, 61 | IndexOptions indexOptions, 62 | int column, 63 | PrimitivePropertyConfiguration propertyConfiguration) 64 | { 65 | var indexAttribute = new IndexAttribute(indexName, column) 66 | { 67 | IsClustered = indexOptions.HasFlag(IndexOptions.Clustered), 68 | IsUnique = indexOptions.HasFlag(IndexOptions.Unique) 69 | }; 70 | 71 | var annotation = GetIndexAnnotation(propertyConfiguration); 72 | if (annotation != null) 73 | { 74 | var attributes = annotation.Indexes.ToList(); 75 | attributes.Add(indexAttribute); 76 | annotation = new IndexAnnotation(attributes); 77 | } 78 | else 79 | { 80 | annotation = new IndexAnnotation(indexAttribute); 81 | } 82 | 83 | propertyConfiguration.HasColumnAnnotation(IndexAnnotation.AnnotationName, annotation); 84 | } 85 | 86 | private static IndexAnnotation GetIndexAnnotation(PrimitivePropertyConfiguration propertyConfiguration) 87 | { 88 | var configuration = typeof (PrimitivePropertyConfiguration) 89 | .GetProperty("Configuration", BindingFlags.Instance | BindingFlags.NonPublic) 90 | .GetValue(propertyConfiguration, null); 91 | 92 | var annotations = (IDictionary) configuration.GetType() 93 | .GetProperty("Annotations", BindingFlags.Instance | BindingFlags.Public) 94 | .GetValue(configuration, null); 95 | 96 | object annotation; 97 | if (!annotations.TryGetValue(IndexAnnotation.AnnotationName, out annotation)) 98 | return null; 99 | 100 | return annotation as IndexAnnotation; 101 | 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /EntityFramework.IndexingExtensions/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | [assembly: AssemblyCompany("Matt Johnson")] 4 | [assembly: AssemblyProduct("EntityFramework.IndexingExtensions")] 5 | [assembly: AssemblyCopyright("Copyright © 2015 Matt Johnson")] 6 | 7 | [assembly: AssemblyTitle("EntityFramework.IndexingExtensions")] 8 | [assembly: AssemblyDescription("Provides extension methods to Entity Framework for simplified fluent configuration of indexes.")] 9 | 10 | [assembly: AssemblyVersion("1.0.1.*")] 11 | [assembly: AssemblyInformationalVersion("1.0.1")] 12 | -------------------------------------------------------------------------------- /EntityFramework.IndexingExtensions/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Matt Johnson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EntityFramework.IndexingExtensions [![NuGet Version](https://img.shields.io/nuget/v/EntityFramework.IndexingExtensions.svg?style=flat)](https://www.nuget.org/packages/EntityFramework.IndexingExtensions/) 2 | Indexing Extensions for Entity Framework 6 3 | 4 | 5 | ### Installation 6 | 7 | ``` 8 | PM> Install-Package EntityFramework.IndexingExtensions 9 | ``` 10 | 11 | ### Usage 12 | 13 | ``` csharp 14 | public class MyDataContext : DbContext 15 | { 16 | protected override void OnModelCreating(DbModelBuilder modelBuilder) 17 | { 18 | modelBuilder.Entity() 19 | .HasIndex("IX_Customers_Name", // Provide the index name. 20 | e => e.Property(x => x.LastName), // Specify at least one column. 21 | e => e.Property(x => x.FirstName)) // Multiple columns as desired. 22 | 23 | .HasIndex("IX_Customers_EmailAddress", // Supports fluent chaining for more indexes. 24 | IndexOptions.Unique, // Supports flags for unique and clustered. 25 | e => e.Property(x => x.EmailAddress)); 26 | } 27 | } 28 | ``` 29 | 30 | ### Notes 31 | 32 | After publishing this, I was informed that there is an active pull request [here](https://entityframework.codeplex.com/SourceControl/network/forks/BrandonDahler/EntityFramework/contribution/7954) to add something similar directly into Entity Framework. If/when that is merged, you should probably use it instead. Though, this one should continue to work without issue. 33 | --------------------------------------------------------------------------------