Skip to content

Commit 8d7a6e4

Browse files
committed
#69: Fix for incorrect Self-Referencing FK created in special case entity names.
1 parent 511d71f commit 8d7a6e4

File tree

9 files changed

+136
-79
lines changed

9 files changed

+136
-79
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using System.Collections.Generic;
2+
using System.ComponentModel.DataAnnotations.Schema;
3+
4+
namespace SQLite.CodeFirst.Console.Entity
5+
{
6+
/// <summary>
7+
/// See https://github.com/msallin/SQLiteCodeFirst/issues/69 and https://github.com/msallin/SQLiteCodeFirst/issues/63
8+
/// </summary>
9+
public class Foo
10+
{
11+
private ICollection<FooSelf> _fooSelves;
12+
private ICollection<FooStep> _fooSteps;
13+
14+
public int FooId { get; set; }
15+
public string Name { get; set; }
16+
public int? FooSelf1Id { get; set; }
17+
public int? FooSelf2Id { get; set; }
18+
public int? FooSelf3Id { get; set; }
19+
20+
[ForeignKey("FooSelf1Id")]
21+
public virtual Foo ParentMyEntity1 { get; set; }
22+
23+
[ForeignKey("FooSelf2Id")]
24+
public virtual Foo ParentMyEntity2 { get; set; }
25+
26+
[ForeignKey("FooSelf3Id")]
27+
public virtual Foo ParentMyEntity3 { get; set; }
28+
29+
public virtual ICollection<FooStep> FooSteps
30+
{
31+
get { return _fooSteps ?? (_fooSteps = new HashSet<FooStep>()); }
32+
set { _fooSteps = value; }
33+
}
34+
35+
public virtual ICollection<FooSelf> FooSelves
36+
{
37+
get { return _fooSelves ?? (_fooSelves = new HashSet<FooSelf>()); }
38+
set { _fooSelves = value; }
39+
}
40+
}
41+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace SQLite.CodeFirst.Console.Entity
2+
{
3+
/// <summary>
4+
/// See https://github.com/msallin/SQLiteCodeFirst/issues/69 and https://github.com/msallin/SQLiteCodeFirst/issues/63
5+
/// </summary>
6+
public class FooSelf
7+
{
8+
public int FooSelfId { get; set; }
9+
public int FooId { get; set; }
10+
public int Number { get; set; }
11+
public virtual Foo Foo { get; set; }
12+
}
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace SQLite.CodeFirst.Console.Entity
2+
{
3+
/// <summary>
4+
/// See https://github.com/msallin/SQLiteCodeFirst/issues/69 and https://github.com/msallin/SQLiteCodeFirst/issues/63
5+
/// </summary>
6+
public class FooStep
7+
{
8+
public int FooStepId { get; set; }
9+
public int FooId { get; set; }
10+
public int Number { get; set; }
11+
public virtual Foo Foo { get; set; }
12+
}
13+
}

SQLite.CodeFirst.Console/Entity/Set.cs

Lines changed: 0 additions & 18 deletions
This file was deleted.
Lines changed: 2 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System.Data.Entity;
2-
using SQLite.CodeFirst.Console.Entity;
32

43
namespace SQLite.CodeFirst.Console
54
{
@@ -14,54 +13,9 @@ public FootballDbContext()
1413

1514
protected override void OnModelCreating(DbModelBuilder modelBuilder)
1615
{
17-
ConfigureTeamEntity(modelBuilder);
18-
ConfigureStadionEntity(modelBuilder);
19-
ConfigureCoachEntity(modelBuilder);
20-
ConfigurePlayerEntity(modelBuilder);
21-
ConfigureSetEntity(modelBuilder);
22-
16+
ModelConfiguration.Configure(modelBuilder);
2317
var initializer = new FootballDbInitializer(modelBuilder);
2418
Database.SetInitializer(initializer);
2519
}
26-
27-
private static void ConfigureTeamEntity(DbModelBuilder modelBuilder)
28-
{
29-
modelBuilder.Entity<Team>().ToTable("Base.MyTable")
30-
.HasRequired(t => t.Coach)
31-
.WithMany()
32-
.WillCascadeOnDelete(false);
33-
34-
modelBuilder.Entity<Team>()
35-
.HasRequired(t => t.Stadion)
36-
.WithRequiredPrincipal()
37-
.WillCascadeOnDelete(true);
38-
}
39-
40-
private static void ConfigureStadionEntity(DbModelBuilder modelBuilder)
41-
{
42-
modelBuilder.Entity<Stadion>();
43-
}
44-
45-
private static void ConfigureCoachEntity(DbModelBuilder modelBuilder)
46-
{
47-
modelBuilder.Entity<Coach>()
48-
.HasRequired(p => p.Team)
49-
.WithRequiredPrincipal(t => t.Coach)
50-
.WillCascadeOnDelete(false);
51-
}
52-
53-
private static void ConfigurePlayerEntity(DbModelBuilder modelBuilder)
54-
{
55-
modelBuilder.Entity<Player>()
56-
.HasRequired(p => p.Team)
57-
.WithMany(team => team.Players)
58-
.WillCascadeOnDelete(true);
59-
}
60-
61-
private static void ConfigureSetEntity(DbModelBuilder modelBuilder)
62-
{
63-
modelBuilder.Entity<Set>()
64-
.HasRequired(s => s.Player);
65-
}
6620
}
67-
}
21+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using System.Data.Entity;
2+
using SQLite.CodeFirst.Console.Entity;
3+
4+
namespace SQLite.CodeFirst.Console
5+
{
6+
public class ModelConfiguration
7+
{
8+
public static void Configure(DbModelBuilder modelBuilder)
9+
{
10+
ConfigureTeamEntity(modelBuilder);
11+
ConfigureStadionEntity(modelBuilder);
12+
ConfigureCoachEntity(modelBuilder);
13+
ConfigurePlayerEntity(modelBuilder);
14+
ConfigureSelfReferencingEntities(modelBuilder);
15+
}
16+
17+
private static void ConfigureTeamEntity(DbModelBuilder modelBuilder)
18+
{
19+
modelBuilder.Entity<Team>().ToTable("Base.MyTable")
20+
.HasRequired(t => t.Coach)
21+
.WithMany()
22+
.WillCascadeOnDelete(false);
23+
24+
modelBuilder.Entity<Team>()
25+
.HasRequired(t => t.Stadion)
26+
.WithRequiredPrincipal()
27+
.WillCascadeOnDelete(true);
28+
}
29+
30+
private static void ConfigureStadionEntity(DbModelBuilder modelBuilder)
31+
{
32+
modelBuilder.Entity<Stadion>();
33+
}
34+
35+
private static void ConfigureCoachEntity(DbModelBuilder modelBuilder)
36+
{
37+
modelBuilder.Entity<Coach>()
38+
.HasRequired(p => p.Team)
39+
.WithRequiredPrincipal(t => t.Coach)
40+
.WillCascadeOnDelete(false);
41+
}
42+
43+
private static void ConfigurePlayerEntity(DbModelBuilder modelBuilder)
44+
{
45+
modelBuilder.Entity<Player>()
46+
.HasRequired(p => p.Team)
47+
.WithMany(team => team.Players)
48+
.WillCascadeOnDelete(true);
49+
}
50+
51+
private static void ConfigureSelfReferencingEntities(DbModelBuilder modelBuilder)
52+
{
53+
modelBuilder.Entity<Foo>();
54+
modelBuilder.Entity<FooSelf>();
55+
modelBuilder.Entity<FooStep>();
56+
}
57+
}
58+
}

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,14 @@
8080
<Compile Include="Entity\IEntity.cs" />
8181
<Compile Include="Entity\Person.cs" />
8282
<Compile Include="Entity\Player.cs" />
83-
<Compile Include="Entity\Set.cs" />
8483
<Compile Include="Entity\Stadion.cs" />
8584
<Compile Include="Entity\Team.cs" />
85+
<Compile Include="Entity\Foo.cs" />
86+
<Compile Include="Entity\FooSelf.cs" />
87+
<Compile Include="Entity\FooStep.cs" />
8688
<Compile Include="FootballDbContext.cs" />
8789
<Compile Include="FootballDbInitializer.cs" />
90+
<Compile Include="ModelConfiguration.cs" />
8891
<Compile Include="Program.cs" />
8992
<Compile Include="Properties\AssemblyInfo.cs" />
9093
</ItemGroup>

SQLite.CodeFirst/Internal/Utility/SqliteAssociationType.cs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ namespace SQLite.CodeFirst.Utility
77
{
88
internal class SqliteAssociationType
99
{
10-
private const string SelfReferencingPostfix = "Self";
11-
1210
public SqliteAssociationType(AssociationType associationType, EntityContainer container)
1311
{
1412
FromRoleEntitySetName = associationType.Constraint.FromRole.Name;
@@ -36,15 +34,10 @@ public SqliteAssociationType(AssociationType associationType, EntityContainer co
3634

3735
private static bool IsSelfReferencing(AssociationType associationType)
3836
{
39-
string to = associationType.Constraint.ToRole.Name;
40-
string from = associationType.Constraint.FromRole.Name;
41-
42-
if (to.Length <= SelfReferencingPostfix.Length)
43-
{
44-
return false;
45-
}
46-
47-
return to.Remove(to.Length - SelfReferencingPostfix.Length, SelfReferencingPostfix.Length) == from;
37+
var toRoleRefType = (RefType)associationType.Constraint.ToRole.TypeUsage.EdmType;
38+
var fromRoleRefType = (RefType)associationType.Constraint.FromRole.TypeUsage.EdmType;
39+
bool isSelfReferencing = toRoleRefType.ElementType.Name == fromRoleRefType.ElementType.Name;
40+
return isSelfReferencing;
4841
}
4942

5043
public string ToRoleEntitySetName { get; set; }

SQLite.CodeFirst/Public/DbInitializers/SqliteDropCreateDatabaseWhenModelChanges.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public override void InitializeDatabase(TContext context)
8989
}
9090
}
9191

92-
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.GC.Collect", Justification = "Required.")]
92+
[SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.GC.Collect", Justification = "Required.")]
9393
private static void DeleteDatabase(TContext context, string databseFilePath)
9494
{
9595
context.Database.Connection.Close();

0 commit comments

Comments
 (0)