Skip to content

Commit 3670d27

Browse files
committed
Merge pull request #1 from msallin/master
Merge
2 parents aa6dae0 + f85bcca commit 3670d27

34 files changed

+640
-261
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,3 +181,6 @@ UpgradeLog*.htm
181181

182182
# Microsoft Fakes
183183
FakesAssemblies/
184+
185+
# Custom
186+
*.GhostDoc.xml

README.md

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,62 @@
11
# SQLite CodeFirst
2+
**Release Build** [![Build status](https://ci.appveyor.com/api/projects/status/2qavdqctw0ehscm6/branch/master?svg=true)](https://ci.appveyor.com/project/msallin/sqlitecodefirst-nv6vn/branch/master)
3+
4+
**CI Build** [![Build status](https://ci.appveyor.com/api/projects/status/oc1miog385h801qe?svg=true)](https://ci.appveyor.com/project/msallin/sqlitecodefirst)
5+
26
Creates a [SQLite Database](https://sqlite.org/) from Code, using [Entity Framework](https://msdn.microsoft.com/en-us/data/ef.aspx) CodeFirst.
37

4-
This Project ships a `SqliteContextInitializer` which creates a new SQLite Database, based on your model/code.
8+
This Project ships several `IDbInitializer` which creates a new SQLite Database, based on your model/code.
59
I started with the [code](https://gist.github.com/flaub/1968486e1b3f2b9fddaf) from [flaub](https://github.com/flaub).
610

711
Currently the following is supported:
8-
- Tables from classes (with table annotation)
9-
- Columns from properties
10-
- ForeignKey constraint (1-n relationships)
11-
- Cascade on delete
12-
- PrimaryKey constraint (An int PrimaryKey will automatically be incremented)
12+
- Tables from classes (supported annotations: `Table`)
13+
- Columns from properties (supported annotations: `Column`, `Key`, `MaxLength`, `Required`, `NotMapped`, `DatabaseGenerated`)
14+
- PrimaryKey constraint (`Key` annotation, key composites are supported)
15+
- ForeignKey constraint (1-n relationships, support for 'Cascade on delete')
1316
- Not Null constraint
17+
- Auto increment (An int PrimaryKey will automatically be incremented)
1418

1519
I tried to write the code in a extensible way.
16-
The logic is devided into two main parts. Builder and Statement.
17-
The Builder-Part knows how to translate the EdmModel into statements where a statement class creates the SQLite-SQL-Code. The structure of the statements is influenced by the [SQLite Language Specification](https://www.sqlite.org/lang.html).
20+
The logic is divided into two main parts. Builder and Statement.
21+
The Builder knows how to translate the EdmModel into statements where a statement class creates the SQLite-DDL-Code.
22+
The structure of the statements is influenced by the [SQLite Language Specification](https://www.sqlite.org/lang.html).
23+
You will find an extensive usage of the composite pattern.
1824

1925
## How to use
20-
If you want to let the Entity Framework create the database, if it does not exist, just set `SqliteContextInitializer<>` as your `IDbInitializer`.
26+
Either get the assembly from the latest [release](https://github.com/msallin/SQLiteCodeFirst/releases) or install the NuGet-Package [SQLite.CodeFirst](https://www.nuget.org/packages/SQLite.CodeFirst/).
27+
28+
If you want to let the Entity Framework create the database, if it does not exist, just set `SqliteDropCreateDatabaseAlways<>` or `SqliteCreateDatabaseIfNotExists<>` as your `IDbInitializer<>`.
2129
```csharp
2230
public class MyDbContext : DbContext
2331
{
24-
public TestDbContext()
32+
public MyDbContext()
2533
: base("ConnectionStringName") { }
2634

2735
protected override void OnModelCreating(DbModelBuilder modelBuilder)
2836
{
29-
var sqliteConnectionInitializer = new SqliteContextInitializer<TestDbContext>(
37+
var sqliteConnectionInitializer = new SqliteCreateDatabaseIfNotExists<MyDbContext>(
3038
Database.Connection.ConnectionString, modelBuilder);
3139
Database.SetInitializer(sqliteConnectionInitializer);
3240
}
3341
}
3442
```
3543

36-
In a more advanced szenario you may want to populate some core- or test-data after the database was created.
37-
To do this, inherit from `SqliteContextInitializer<>` and override the `Seed(TestDbContext context)` function.
44+
In a more advanced scenario you may want to populate some core- or test-data after the database was created.
45+
To do this, inherit from `SqliteDropCreateDatabaseAlways<>` or `SqliteCreateDatabaseIfNotExists<>` and override the `Seed(MyDbContext context)` function.
3846
This function will be called, in a own transaction, right after the database was created. This function is only executed if a new database was successfully created.
3947
```csharp
40-
public class TestDbContextInitializer : SqliteContextInitializer<TestDbContext>
48+
public class MyDbContextContextInitializer : SqliteDropCreateDatabaseAlways<MyDbContext>
4149
{
42-
public TestDbContextInitializer(string connectionString, DbModelBuilder modelBuilder)
50+
public MyDbContextInitializer(string connectionString, DbModelBuilder modelBuilder)
4351
: base(connectionString, modelBuilder) { }
4452

45-
protected override void Seed(TestDbContext context)
53+
protected override void Seed(MyDbContext context)
4654
{
4755
context.Set<Player>().Add(new Player());
4856
}
4957
}
5058
```
59+
60+
## Hints
61+
If you try to reinstall the NuGet-Packages (e.g. if you want to downgrade to .NET 4.0) the app.config will be overwritten and you may gettubg an exception when you try to run the console project.
62+
In this case please check the following issue: https://github.com/msallin/SQLiteCodeFirst/issues/13.

SQLite.CodeFirst.Console/App.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
55
</configSections>
66
<connectionStrings>
7-
<add name="test" connectionString="data source=C:\temp\testdb.sqlite" providerName="System.Data.SQLite" />
7+
<add name="footballDb" connectionString="data source=.\footballDb.sqlite" providerName="System.Data.SQLite" />
88
</connectionStrings>
99
<startup>
1010
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,25 @@
1-

1+
using System.ComponentModel.DataAnnotations;
2+
using System.ComponentModel.DataAnnotations.Schema;
3+
24
namespace SQLite.CodeFirst.Console.Entity
35
{
6+
[Table("TeamPlayer")]
47
public class Player : IEntity
58
{
69
public int Id { get; set; }
7-
public string Name { get; set; }
8-
public Team Team { get; set; }
10+
11+
[MaxLength(50)]
12+
public string FirstName { get; set; }
13+
14+
[MaxLength(50)]
15+
public string LastName { get; set; }
16+
17+
[MaxLength(100)]
18+
public string Street { get; set; }
19+
20+
[Required]
21+
public string City { get; set; }
22+
23+
public virtual Team Team { get; set; }
924
}
1025
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System.ComponentModel.DataAnnotations;
2+
using System.ComponentModel.DataAnnotations.Schema;
3+
4+
namespace SQLite.CodeFirst.Console.Entity
5+
{
6+
public class Stadion
7+
{
8+
[Key]
9+
[Column(Order = 1)]
10+
public string Name { get; set; }
11+
12+
[Key]
13+
[Column(Order = 2)]
14+
public string Street { get; set; }
15+
16+
[Key]
17+
[Column(Order = 3)]
18+
public string City { get; set; }
19+
}
20+
}
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
using System.Collections.Generic;
2+
using System.ComponentModel.DataAnnotations;
23

34
namespace SQLite.CodeFirst.Console.Entity
45
{
56
public class Team : IEntity
67
{
78
public int Id { get; set; }
8-
public ICollection<Player> Players { get; set; }
9+
10+
[Required]
11+
public string Name { get; set; }
12+
13+
public virtual ICollection<Player> Players { get; set; }
14+
15+
public virtual Stadion Stadion { get; set; }
916
}
1017
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
using System.Collections.Generic;
2+
using System.Data.Entity;
3+
using System.Data.Entity.ModelConfiguration.Conventions;
4+
using SQLite.CodeFirst.Console.Entity;
5+
6+
namespace SQLite.CodeFirst.Console
7+
{
8+
public class FootballDbContext : DbContext
9+
{
10+
public FootballDbContext()
11+
: base("footballDb")
12+
{
13+
Configuration.ProxyCreationEnabled = true;
14+
Configuration.LazyLoadingEnabled = true;
15+
}
16+
17+
protected override void OnModelCreating(DbModelBuilder modelBuilder)
18+
{
19+
ConfigureTeamEntity(modelBuilder);
20+
ConfigureStadionEntity(modelBuilder);
21+
ConfigurePlayerEntity(modelBuilder);
22+
23+
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
24+
25+
var initializer = new FootballDbInitializer(Database.Connection.ConnectionString, modelBuilder);
26+
Database.SetInitializer(initializer);
27+
}
28+
29+
private static void ConfigureTeamEntity(DbModelBuilder modelBuilder)
30+
{
31+
modelBuilder.Entity<Team>();
32+
}
33+
34+
private static void ConfigureStadionEntity(DbModelBuilder modelBuilder)
35+
{
36+
modelBuilder.Entity<Stadion>();
37+
}
38+
39+
private static void ConfigurePlayerEntity(DbModelBuilder modelBuilder)
40+
{
41+
modelBuilder.Entity<Player>()
42+
.HasRequired(p => p.Team)
43+
.WithMany(team => team.Players)
44+
.WillCascadeOnDelete(true);
45+
}
46+
}
47+
48+
public class FootballDbInitializer : SqliteDropCreateDatabaseAlways<FootballDbContext>
49+
{
50+
public FootballDbInitializer(string connectionString, DbModelBuilder modelBuilder)
51+
: base(connectionString, modelBuilder) { }
52+
53+
protected override void Seed(FootballDbContext context)
54+
{
55+
context.Set<Team>().Add(new Team
56+
{
57+
Name = "YB",
58+
Players = new List<Player>
59+
{
60+
new Player
61+
{
62+
City = "Bern",
63+
FirstName = "Marco",
64+
LastName = "Bürki",
65+
Street = "Wunderstrasse 43"
66+
},
67+
new Player
68+
{
69+
City = "Berlin",
70+
FirstName = "Alain",
71+
LastName = "Rochat",
72+
Street = "Wonderstreet 13"
73+
}
74+
},
75+
Stadion = new Stadion
76+
{
77+
Name = "Stade de Suisse",
78+
City = "Bern",
79+
Street = "Papiermühlestrasse 71"
80+
}
81+
});
82+
}
83+
}
84+
}

SQLite.CodeFirst.Console/Program.cs

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,63 @@
1-
using System.Linq;
2-
using SQLite.CodeFirst.Console.Entity;
1+
using SQLite.CodeFirst.Console.Entity;
32

43
namespace SQLite.CodeFirst.Console
54
{
65
public static class Program
76
{
87
static void Main()
98
{
10-
var context = new TestDbContext();
11-
System.Console.WriteLine(context.Set<Player>().Count());
9+
System.Console.WriteLine("Starting Demo Application");
10+
11+
var context = CreateAndSeedDatabase();
12+
13+
DisplaySeededData(context);
14+
15+
PressEnterToExit();
16+
}
17+
18+
private static FootballDbContext CreateAndSeedDatabase()
19+
{
20+
System.Console.WriteLine("Create and seed the database.");
21+
var context = new FootballDbContext();
22+
System.Console.WriteLine("Completed.");
23+
System.Console.WriteLine();
24+
return context;
25+
}
26+
27+
private static void DisplaySeededData(FootballDbContext context)
28+
{
29+
System.Console.WriteLine("Display seeded data.");
30+
31+
foreach (var team in context.Set<Team>())
32+
{
33+
System.Console.WriteLine("\t Team:");
34+
System.Console.WriteLine("\t Id: {0}", team.Id);
35+
System.Console.WriteLine("\t Name: {0}", team.Name);
36+
System.Console.WriteLine();
37+
38+
System.Console.WriteLine("\t\t Stadion:");
39+
System.Console.WriteLine("\t\t Name: {0}", team.Stadion.Name);
40+
System.Console.WriteLine("\t\t Street: {0}", team.Stadion.Street);
41+
System.Console.WriteLine("\t\t City: {0}", team.Stadion.City);
42+
System.Console.WriteLine();
43+
44+
foreach (var player in team.Players)
45+
{
46+
System.Console.WriteLine("\t\t Player:");
47+
System.Console.WriteLine("\t\t Id: {0}", player.Id);
48+
System.Console.WriteLine("\t\t FirstName: {0}", player.FirstName);
49+
System.Console.WriteLine("\t\t LastName: {0}", player.LastName);
50+
System.Console.WriteLine("\t\t Street: {0}", player.Street);
51+
System.Console.WriteLine("\t\t City: {0}", player.City);
52+
System.Console.WriteLine();
53+
}
54+
}
55+
}
56+
57+
private static void PressEnterToExit()
58+
{
59+
System.Console.WriteLine();
60+
System.Console.WriteLine("Press 'Enter' to exit.");
1261
System.Console.ReadLine();
1362
}
1463
}
Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,10 @@
11
using System.Reflection;
2-
using System.Runtime.CompilerServices;
32
using System.Runtime.InteropServices;
43

5-
// General Information about an assembly is controlled through the following
6-
// set of attributes. Change these attribute values to modify the information
7-
// associated with an assembly.
8-
[assembly: AssemblyTitle("SQLite.CodeFirst.Console")]
9-
[assembly: AssemblyDescription("")]
10-
[assembly: AssemblyConfiguration("")]
11-
[assembly: AssemblyCompany("")]
4+
[assembly: AssemblyTitle("SQLite.CodeFirst")]
5+
[assembly: AssemblyDescription("A console application which demonstrates how to use QLite.CodeFirst.")]
126
[assembly: AssemblyProduct("SQLite.CodeFirst")]
13-
[assembly: AssemblyCopyright("Copyright © 2015")]
14-
[assembly: AssemblyTrademark("")]
15-
[assembly: AssemblyCulture("")]
7+
[assembly: AssemblyCopyright("Copyright © Marc Sallin")]
168

179
// Setting ComVisible to false makes the types in this assembly not visible
1810
// to COM components. If you need to access a type in this assembly from
@@ -22,15 +14,6 @@
2214
// The following GUID is for the ID of the typelib if this project is exposed to COM
2315
[assembly: Guid("945f6a68-1bcd-47ff-a551-a2820b88ff8c")]
2416

25-
// Version information for an assembly consists of the following four values:
26-
//
27-
// Major Version
28-
// Minor Version
29-
// Build Number
30-
// Revision
31-
//
32-
// You can specify all the values or you can default the Build and Revision Numbers
33-
// by using the '*' as shown below:
34-
// [assembly: AssemblyVersion("1.0.*")]
3517
[assembly: AssemblyVersion("1.0.0.0")]
3618
[assembly: AssemblyFileVersion("1.0.0.0")]
19+
[assembly: AssemblyInformationalVersion("1.0.0.0")]

SQLite.CodeFirst.Console/SQLite.CodeFirst.Console.csproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
</Reference>
4545
<Reference Include="System" />
4646
<Reference Include="System.ComponentModel.DataAnnotations" />
47+
<Reference Include="System.Configuration" />
4748
<Reference Include="System.Core" />
4849
<Reference Include="System.Data.SQLite">
4950
<HintPath>..\packages\System.Data.SQLite.Core.1.0.96.0\lib\net451\System.Data.SQLite.dll</HintPath>
@@ -63,8 +64,9 @@
6364
<ItemGroup>
6465
<Compile Include="Entity\IEntity.cs" />
6566
<Compile Include="Entity\Player.cs" />
67+
<Compile Include="Entity\Stadion.cs" />
6668
<Compile Include="Entity\Team.cs" />
67-
<Compile Include="TestDbContext.cs" />
69+
<Compile Include="FootballDbContext.cs" />
6870
<Compile Include="Program.cs" />
6971
<Compile Include="Properties\AssemblyInfo.cs" />
7072
</ItemGroup>

0 commit comments

Comments
 (0)