Skip to content

Commit 69b677e

Browse files
author
Marc Sallin
committed
Merge pull request #17 from msallin/Index_Implementation
Index implementation
2 parents f85bcca + 31ec481 commit 69b677e

File tree

10 files changed

+176
-22
lines changed

10 files changed

+176
-22
lines changed

SQLite.CodeFirst.Console/Entity/Player.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ public class Player : IEntity
88
{
99
public int Id { get; set; }
1010

11+
[Index] // Automatically named 'IX_FirstName'
1112
[MaxLength(50)]
1213
public string FirstName { get; set; }
1314

15+
[Index("IX_LN")]
1416
[MaxLength(50)]
1517
public string LastName { get; set; }
1618

SQLite.CodeFirst.Console/Entity/Stadion.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ public class Stadion
77
{
88
[Key]
99
[Column(Order = 1)]
10+
[Index("IX_Main", Order = 2)]
1011
public string Name { get; set; }
1112

1213
[Key]
1314
[Column(Order = 2)]
15+
[Index("IX_Main", Order = 1)]
1416
public string Street { get; set; }
1517

1618
[Key]

SQLite.CodeFirst/Builder/CreateDatabaseStatementBuilder.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ public CreateDatabaseStatementBuilder(EdmModel edmModel)
1616

1717
public CreateDatabaseStatement BuildStatement()
1818
{
19-
var createDatabaseStatement = new CreateDatabaseStatement(GetCreateTableStatements());
19+
var createTableStatements = GetCreateTableStatements();
20+
var createIndexStatements = GetCreateIndexStatements();
21+
var createStatements = createTableStatements.Concat<IStatement>(createIndexStatements);
22+
var createDatabaseStatement = new CreateDatabaseStatement(createStatements);
2023
return createDatabaseStatement;
2124
}
2225

@@ -31,5 +34,14 @@ private IEnumerable<CreateTableStatement> GetCreateTableStatements()
3134
yield return tableStatementBuilder.BuildStatement();
3235
}
3336
}
37+
38+
private IEnumerable<CreateIndexStatementCollection> GetCreateIndexStatements()
39+
{
40+
foreach (var entityType in edmModel.EntityTypes)
41+
{
42+
var indexStatementBuilder = new CreateIndexStatementBuilder(entityType);
43+
yield return indexStatementBuilder.BuildStatement();
44+
}
45+
}
3446
}
35-
}
47+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
using System.Collections.Generic;
2+
using System.Collections.ObjectModel;
3+
using System.ComponentModel.DataAnnotations.Schema;
4+
using System.Data.Entity.Core.Metadata.Edm;
5+
using System.Data.Entity.Infrastructure.Annotations;
6+
using System.Linq;
7+
using SQLite.CodeFirst.Extensions;
8+
using SQLite.CodeFirst.Statement;
9+
10+
namespace SQLite.CodeFirst.Builder
11+
{
12+
internal class CreateIndexStatementBuilder : IStatementBuilder<CreateIndexStatementCollection>
13+
{
14+
private readonly EntityType entityType;
15+
16+
public CreateIndexStatementBuilder(EntityType entityType)
17+
{
18+
this.entityType = entityType;
19+
}
20+
21+
public CreateIndexStatementCollection BuildStatement()
22+
{
23+
IDictionary<string, CreateIndexStatement> createIndexStatments = new Dictionary<string, CreateIndexStatement>();
24+
25+
foreach (var edmProperty in entityType.Properties)
26+
{
27+
var indexAnnotations = edmProperty.MetadataProperties
28+
.Select(x => x.Value)
29+
.OfType<IndexAnnotation>();
30+
31+
foreach (var index in indexAnnotations.SelectMany(ia => ia.Indexes))
32+
{
33+
CreateIndexStatement createIndexStatement;
34+
string indexName = GetIndexName(index, edmProperty);
35+
if (!createIndexStatments.TryGetValue(indexName, out createIndexStatement))
36+
{
37+
createIndexStatement = new CreateIndexStatement
38+
{
39+
IsUnique = index.IsUnique,
40+
Name = indexName,
41+
Table = entityType.GetTableName(),
42+
Columns = new Collection<CreateIndexStatement.IndexColumn>()
43+
};
44+
createIndexStatments.Add(indexName, createIndexStatement);
45+
}
46+
47+
createIndexStatement.Columns.Add(new CreateIndexStatement.IndexColumn
48+
{
49+
Name = edmProperty.Name,
50+
Order = index.Order
51+
});
52+
}
53+
}
54+
55+
return new CreateIndexStatementCollection(createIndexStatments.Values);
56+
}
57+
58+
private static string GetIndexName(IndexAttribute index, EdmProperty property)
59+
{
60+
return index.Name ?? "IX_" + property.Name;
61+
}
62+
}
63+
}
Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using System.Collections.Generic;
22
using System.Data.Entity.Core.Metadata.Edm;
3-
using System.Linq;
3+
using SQLite.CodeFirst.Extensions;
44
using SQLite.CodeFirst.Statement;
55

66
namespace SQLite.CodeFirst.Builder
@@ -22,27 +22,16 @@ public CreateTableStatement BuildStatement()
2222
var primaryKeyStatement = new PrimaryKeyStatementBuilder(entityType.KeyMembers).BuildStatement();
2323
var foreignKeyCollection = new ForeignKeyStatementBuilder(associationTypes).BuildStatement();
2424

25-
List<IStatement> columnStatements = new List<IStatement>();
25+
var columnStatements = new List<IStatement>();
2626
columnStatements.AddRange(simpleColumnCollection);
2727
columnStatements.Add(primaryKeyStatement);
2828
columnStatements.AddRange(foreignKeyCollection);
2929

3030
return new CreateTableStatement
3131
{
32-
TableName = GetTableName(),
32+
TableName = entityType.GetTableName(),
3333
ColumnStatementCollection = new ColumnStatementCollection(columnStatements)
3434
};
3535
}
36-
37-
private string GetTableName()
38-
{
39-
MetadataProperty metadataProperty;
40-
if (entityType.MetadataProperties.TryGetValue("TableName", false, out metadataProperty))
41-
{
42-
return metadataProperty.Value.ToString();
43-
}
44-
45-
return entityType.Name;
46-
}
4736
}
4837
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System.Data.Entity.Core.Metadata.Edm;
2+
3+
namespace SQLite.CodeFirst.Extensions
4+
{
5+
internal static class EntityTypeExtension
6+
{
7+
public static string GetTableName(this EntityType entityType)
8+
{
9+
MetadataProperty metadataProperty;
10+
if (entityType.MetadataProperties.TryGetValue("TableName", false, out metadataProperty))
11+
{
12+
return metadataProperty.Value.ToString();
13+
}
14+
15+
return entityType.Name;
16+
}
17+
}
18+
}

SQLite.CodeFirst/SQLite.CodeFirst.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,16 @@
4949
</ItemGroup>
5050
<ItemGroup>
5151
<Compile Include="Builder\ColumnStatementCollectionBuilder.cs" />
52+
<Compile Include="Builder\CreateIndexStatementBuilder.cs" />
5253
<Compile Include="Builder\ForeignKeyStatementBuilder.cs" />
5354
<Compile Include="Builder\CreateDatabaseStatementBuilder.cs" />
5455
<Compile Include="Builder\PrimaryKeyStatementBuilder.cs" />
56+
<Compile Include="Extensions\EntityTypeExtension.cs" />
5557
<Compile Include="SqliteCreateDatabaseIfNotExists.cs" />
5658
<Compile Include="SqliteDropCreateDatabaseAlways.cs" />
5759
<Compile Include="Statement\ColumnConstraint\MaxLengthConstraint.cs" />
60+
<Compile Include="Statement\CreateIndexStatement.cs" />
61+
<Compile Include="Statement\CreateIndexStatementCollection.cs" />
5862
<Compile Include="Statement\PrimaryKeyStatement.cs" />
5963
<Compile Include="Properties\AssemblyInfo.cs" />
6064
<Compile Include="SqliteConnectionStringParser.cs" />

SQLite.CodeFirst/Statement/CreateDatabaseStatement.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,23 @@
55

66
namespace SQLite.CodeFirst.Statement
77
{
8-
internal class CreateDatabaseStatement : Collection<CreateTableStatement>, IStatement
8+
internal class CreateDatabaseStatement : Collection<IStatement>, IStatement
99
{
10-
private const string CreateTableStatementSeperator = "\r\n";
10+
private const string StatementSeperator = "\r\n";
1111

1212
public CreateDatabaseStatement() { }
1313

14-
public CreateDatabaseStatement(IEnumerable<CreateTableStatement> createTableStatements)
14+
public CreateDatabaseStatement(IEnumerable<IStatement> statements)
1515
{
16-
foreach (var createTableStatement in createTableStatements)
16+
foreach (var statement in statements)
1717
{
18-
Add(createTableStatement);
18+
Add(statement);
1919
}
2020
}
2121

2222
public string CreateStatement()
2323
{
24-
return String.Join(CreateTableStatementSeperator, this.Select(c => c.CreateStatement()));
24+
return String.Join(StatementSeperator, this.Select(c => c.CreateStatement()));
2525
}
2626
}
2727
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
namespace SQLite.CodeFirst.Statement
7+
{
8+
internal class CreateIndexStatement : IStatement
9+
{
10+
private const string Template = "CREATE {unique} INDEX {index-name} ON {table-name} ({column-def});";
11+
private const string ColumnNameSeperator = ", ";
12+
13+
public string Name { get; set; }
14+
public string Table { get; set; }
15+
public ICollection<IndexColumn> Columns { get; set; }
16+
public bool IsUnique { get; set; }
17+
18+
public string CreateStatement()
19+
{
20+
var stringBuilder = new StringBuilder(Template);
21+
22+
stringBuilder.Replace("{unique}", IsUnique ? "UNIQUE" : string.Empty);
23+
stringBuilder.Replace("{index-name}", Name);
24+
stringBuilder.Replace("{table-name}", Table);
25+
26+
IEnumerable<string> orderedColumnNames = Columns.OrderBy(c => c.Order).Select(c => c.Name);
27+
string columnDefinition = String.Join(ColumnNameSeperator, orderedColumnNames);
28+
stringBuilder.Replace("{column-def}", columnDefinition);
29+
30+
return stringBuilder.ToString();
31+
}
32+
33+
public class IndexColumn
34+
{
35+
public int Order { get; set; }
36+
public string Name { get; set; }
37+
}
38+
}
39+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Collections.ObjectModel;
4+
using System.Linq;
5+
6+
namespace SQLite.CodeFirst.Statement
7+
{
8+
internal class CreateIndexStatementCollection : Collection<CreateIndexStatement>, IStatement
9+
{
10+
private const string StatementSeperator = "\r\n";
11+
12+
public CreateIndexStatementCollection(IEnumerable<CreateIndexStatement> createIndexStatements)
13+
{
14+
foreach (var createIndexStatement in createIndexStatements)
15+
{
16+
Add(createIndexStatement);
17+
}
18+
}
19+
20+
public string CreateStatement()
21+
{
22+
return String.Join(StatementSeperator, this.Select(e => e.CreateStatement()));
23+
}
24+
}
25+
}

0 commit comments

Comments
 (0)