Skip to content

Commit 69caf3a

Browse files
committed
Allow override of cardinality on With clauses
1 parent 231e362 commit 69caf3a

2 files changed

Lines changed: 57 additions & 19 deletions

File tree

Simple.Data.Ado/QueryBuilder.cs

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -110,28 +110,11 @@ private void HandleWithClauses()
110110
{
111111
if (withClause.ObjectReference.GetOwner().IsNull())
112112
{
113-
var joinClause =
114-
_query.Clauses.OfType<JoinClause>().FirstOrDefault(j => j.Table.GetAliasOrName() == withClause.ObjectReference.GetAliasOrName());
115-
if (joinClause != null)
116-
{
117-
_columns =
118-
_columns.Concat(
119-
_schema.FindTable(joinClause.Table.GetName()).Columns.Select(
120-
c => new ObjectReference(c.ActualName, joinClause.Table)))
121-
.ToArray();
122-
relationTypeDict[joinClause.Table] = withClause.Type == WithType.One
123-
? RelationType.ManyToOne
124-
: RelationType.OneToMany;
125-
}
113+
HandleWithClauseUsingAssociatedJoinClause(relationTypeDict, withClause);
126114
}
127115
else
128116
{
129-
relationTypeDict[withClause.ObjectReference] = RelationType.None;
130-
_columns =
131-
_columns.Concat(
132-
_schema.FindTable(withClause.ObjectReference.GetName()).Columns.Select(
133-
c => new ObjectReference(c.ActualName, withClause.ObjectReference)))
134-
.ToArray();
117+
HandleWithClauseUsingNaturalJoin(withClause, relationTypeDict);
135118
}
136119
}
137120
_columns =
@@ -141,6 +124,45 @@ private void HandleWithClauses()
141124
}
142125
}
143126

127+
private void HandleWithClauseUsingAssociatedJoinClause(Dictionary<ObjectReference, RelationType> relationTypeDict, WithClause withClause)
128+
{
129+
var joinClause =
130+
_query.Clauses.OfType<JoinClause>().FirstOrDefault(
131+
j => j.Table.GetAliasOrName() == withClause.ObjectReference.GetAliasOrName());
132+
if (joinClause != null)
133+
{
134+
_columns =
135+
_columns.Concat(
136+
_schema.FindTable(joinClause.Table.GetName()).Columns.Select(
137+
c => new ObjectReference(c.ActualName, joinClause.Table)))
138+
.ToArray();
139+
relationTypeDict[joinClause.Table] = WithTypeToRelationType(withClause.Type, RelationType.OneToMany);
140+
}
141+
}
142+
143+
private void HandleWithClauseUsingNaturalJoin(WithClause withClause, Dictionary<ObjectReference, RelationType> relationTypeDict)
144+
{
145+
relationTypeDict[withClause.ObjectReference] = WithTypeToRelationType(withClause.Type, RelationType.None);
146+
_columns =
147+
_columns.Concat(
148+
_schema.FindTable(withClause.ObjectReference.GetName()).Columns.Select(
149+
c => new ObjectReference(c.ActualName, withClause.ObjectReference)))
150+
.ToArray();
151+
}
152+
153+
private static RelationType WithTypeToRelationType(WithType withType, RelationType defaultRelationType)
154+
{
155+
switch (withType)
156+
{
157+
case WithType.One:
158+
return RelationType.ManyToOne;
159+
case WithType.Many:
160+
return RelationType.OneToMany;
161+
default:
162+
return defaultRelationType;
163+
}
164+
}
165+
144166
private bool IsCoreTable(ObjectReference tableReference)
145167
{
146168
if (ReferenceEquals(tableReference, null)) throw new ArgumentNullException("tableReference");

Simple.Data.BehaviourTest/Query/WithTest.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,22 @@ public void SingleWithClauseUsingReferenceShouldUseJoin()
8282
GeneratedSqlIs(expectedSql);
8383
}
8484

85+
[Test]
86+
public void SingleWithOneClauseUsingReferenceShouldUseJoinAndForceOne()
87+
{
88+
const string expectedSql = "select " +
89+
"[dbo].[department].[id],[dbo].[department].[name]," +
90+
"[dbo].[employee].[id] as [__with1__employee__id],[dbo].[employee].[name] as [__with1__employee__name]," +
91+
"[dbo].[employee].[managerid] as [__with1__employee__managerid],[dbo].[employee].[departmentid] as [__with1__employee__departmentid]" +
92+
" from [dbo].[department] left join [dbo].[employee] on ([dbo].[department].[id] = [dbo].[employee].[departmentid])";
93+
94+
var q = _db.Departments.All().WithOne(_db.Departments.Employee);
95+
96+
EatException(() => q.ToList());
97+
98+
GeneratedSqlIs(expectedSql);
99+
}
100+
85101
[Test]
86102
public void SingleWithClauseUsingReferenceWithAliasShouldApplyAliasToSql()
87103
{

0 commit comments

Comments
 (0)