Skip to content

Commit 2f74d15

Browse files
committed
Fixed issue ThatRendle#164
1 parent 28da710 commit 2f74d15

6 files changed

Lines changed: 66 additions & 17 deletions

File tree

Simple.Data.Ado/Joiner.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,10 @@ private void AddJoin(ObjectName table1Name, ObjectName table2Name, JoinType join
103103
private static ForeignKey GetForeignKey(Table table1, Table table2)
104104
{
105105
var foreignKey =
106-
table2.ForeignKeys.SingleOrDefault(
106+
table2.ForeignKeys.FirstOrDefault(
107107
fk => fk.MasterTable.Schema == table1.Schema && fk.MasterTable.Name == table1.ActualName)
108108
??
109-
table1.ForeignKeys.SingleOrDefault(
109+
table1.ForeignKeys.FirstOrDefault(
110110
fk => fk.MasterTable.Schema == table2.Schema && fk.MasterTable.Name == table2.ActualName);
111111

112112
if (foreignKey == null)

Simple.Data.Ado/Schema/ForeignKey.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,27 @@ public sealed class ForeignKey
77
private readonly Key _columns;
88
private readonly ObjectName _detailTable;
99
private readonly ObjectName _masterTable;
10+
private readonly string _name;
1011
private readonly Key _masterColumns;
1112

12-
public ForeignKey(ObjectName detailTable, IEnumerable<string> columns, ObjectName masterTable, IEnumerable<string> masterColumns)
13+
public ForeignKey(ObjectName detailTable, IEnumerable<string> columns, ObjectName masterTable, IEnumerable<string> masterColumns) : this(detailTable, columns, masterTable, masterColumns, null)
14+
{
15+
}
16+
17+
public ForeignKey(ObjectName detailTable, IEnumerable<string> columns, ObjectName masterTable, IEnumerable<string> masterColumns, string name)
1318
{
1419
_columns = new Key(columns);
1520
_detailTable = detailTable;
1621
_masterTable = masterTable;
22+
_name = name;
1723
_masterColumns = new Key(masterColumns);
1824
}
1925

26+
public string Name
27+
{
28+
get { return _name; }
29+
}
30+
2031
public ObjectName DetailTable
2132
{
2233
get { return _detailTable; }

Simple.Data.Ado/Schema/ForeignKeyCollection.cs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,7 @@
22

33
namespace Simple.Data.Ado.Schema
44
{
5-
public class ForeignKeyCollection : KeyedCollection<ObjectName, ForeignKey>
5+
public class ForeignKeyCollection : Collection<ForeignKey>
66
{
7-
/// <summary>
8-
/// When implemented in a derived class, extracts the key from the specified element.
9-
/// </summary>
10-
/// <returns>
11-
/// The key for the specified element.
12-
/// </returns>
13-
/// <param name="item">The element from which to extract the key.</param>
14-
protected override ObjectName GetKeyForItem(ForeignKey item)
15-
{
16-
return item.MasterTable;
17-
}
187
}
198
}

Simple.Data.Ado/Schema/Table.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ internal TableJoin GetMaster(string name)
145145
var table = _databaseSchema.FindTable(name);
146146

147147
var foreignKey =
148-
this.ForeignKeys.SingleOrDefault(fk => fk.MasterTable.Schema == table.Schema && fk.MasterTable.Name == table.ActualName);
148+
this.ForeignKeys.FirstOrDefault(fk => fk.MasterTable.Schema == table.Schema && fk.MasterTable.Name == table.ActualName);
149149

150150
if (foreignKey == null) return null;
151151

@@ -164,7 +164,7 @@ internal TableJoin GetDetail(string name)
164164
{
165165
var table = DatabaseSchema.FindTable(name);
166166
var foreignKey =
167-
table.ForeignKeys.SingleOrDefault(fk => fk.MasterTable.Schema == this.Schema && fk.MasterTable.Name == this.ActualName);
167+
table.ForeignKeys.FirstOrDefault(fk => fk.MasterTable.Schema == this.Schema && fk.MasterTable.Name == this.ActualName);
168168

169169
if (foreignKey == null) return null;
170170

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
namespace Simple.Data.IntegrationTest
2+
{
3+
using Mocking.Ado;
4+
using NUnit.Framework;
5+
6+
[TestFixture]
7+
public class AmbiguousForeignKeyTest : DatabaseIntegrationContext
8+
{
9+
protected override void SetSchema(MockSchemaProvider schemaProvider)
10+
{
11+
schemaProvider.SetTables(new[] { "dbo", "Fixture", "BASE TABLE" },
12+
new[] { "dbo", "Team", "BASE TABLE" });
13+
schemaProvider.SetColumns(new[] { "dbo", "Team", "Id" },
14+
new[] { "dbo", "Fixture", "Id" },
15+
new[] { "dbo", "Fixture", "HomeTeamId" },
16+
new[] { "dbo", "Fixture", "AwayTeamId" },
17+
new[] { "dbo", "Team", "Name" });
18+
schemaProvider.SetPrimaryKeys(new object[] { "dbo", "Team", "Id", 0 },
19+
new object[] { "dbo", "Team", "Id", 0 });
20+
schemaProvider.SetForeignKeys(new object[] { "FK_Fixture_HomeTeam", "dbo", "Fixture", "HomeTeamId", "dbo", "Team", "Id", 0 },
21+
new object[] { "FK_Fixture_AwayTeam", "dbo", "Fixture", "AwayTeamId", "dbo", "Team", "Id", 0 });
22+
}
23+
24+
[Test]
25+
public void CanSelectTwoWithUsingExplicitJoin()
26+
{
27+
const string expectedSql =
28+
"select [dbo].[Fixture].[Id],[dbo].[Fixture].[HomeTeamId],[dbo].[Fixture].[AwayTeamId],[Home].[Id] AS [__withn__Home__Id],[Home].[Name] AS [__withn__Home__Name]," +
29+
"[Away].[Id] AS [__withn__Away__Id],[Away].[Name] AS [__withn__Away__Name] from [dbo].[Fixture] " +
30+
"JOIN [dbo].[Team] [Home] ON ([dbo].[Fixture].[HomeTeamId] = [Home].[Id]) " +
31+
"JOIN [dbo].[Team] [Away] ON ([dbo].[Fixture].[AwayTeamId] = [Away].[Id])";
32+
33+
dynamic homeTeam;
34+
dynamic awayTeam;
35+
36+
var q = _db.Fixture.All()
37+
.Join(_db.Team.As("Home"), out homeTeam)
38+
.On(_db.Fixture.HomeTeamId == homeTeam.Id)
39+
.Join(_db.Team.As("Away"), out awayTeam)
40+
.On(_db.Fixture.AwayTeamId == awayTeam.Id)
41+
.With(homeTeam)
42+
.With(awayTeam);
43+
44+
EatException(() => q.ToList());
45+
GeneratedSqlIs(expectedSql);
46+
}
47+
}
48+
}

Simple.Data.BehaviourTest/Simple.Data.BehaviourTest.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
</CodeAnalysisDependentAssemblyPaths>
6464
</ItemGroup>
6565
<ItemGroup>
66+
<Compile Include="AmbiguousForeignKeyTest.cs" />
6667
<Compile Include="BulkInsertTest.cs" />
6768
<Compile Include="DatabaseIntegrationContext.cs" />
6869
<Compile Include="DeleteTest.cs" />

0 commit comments

Comments
 (0)