Skip to content

Commit a6189e0

Browse files
authored
Merge pull request #57 from SubSonic-Core/dev/main
#56 when selector returnType is class find the dbTableExpression from…
2 parents 79eacc0 + c1f9ad3 commit a6189e0

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

SubSonic.Core.DataAccessLayer/src/Builders/DbSqlQueryBuilder/DbSqlQueryBuilderBuildMethods.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,25 @@ private Expression BuildSelectWithExpression(MethodCallExpression expression)
624624
switch (selector.Body.NodeType)
625625
{
626626
case ExpressionType.MemberAccess:
627-
columns = select.Columns.Where(column => column.PropertyName.Equals(selector.GetProperty().Name, StringComparison.CurrentCulture));
627+
if (selector.ReturnType.IsClass)
628+
{
629+
IEnumerable<DbTableExpression> tables = select.From.ToTableList();
630+
631+
if (tables.Any(x => x.Type.GenericTypeArguments[0] == selector.ReturnType))
632+
{
633+
DbTableExpression dbTable = tables.Single(x => x.Type.GenericTypeArguments[0] == selector.ReturnType);
634+
635+
columns = dbTable.Columns;
636+
}
637+
else
638+
{
639+
throw Error.InvalidOperation(SubSonicErrorMessages.MissingTableReferenceFor.Format(selector.ReturnType.Name));
640+
}
641+
}
642+
else
643+
{
644+
columns = select.Columns.Where(column => column.PropertyName.Equals(selector.GetProperty().Name, StringComparison.CurrentCulture));
645+
}
628646
break;
629647
case ExpressionType.MemberInit:
630648
columns = BuildColumnDeclarationList(selector.Body, select);

SubSonic.Tests/DAL/SqlQueryProvider/SqlGeneratorTests.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ namespace SubSonic.Tests.DAL.SqlQueryProvider
1616
using Linq;
1717
using Linq.Expressions;
1818
using Tests.DAL.SUT;
19+
using SubSonic.src;
1920

2021
[TestFixture]
2122
public partial class SqlQueryProviderTests
@@ -1092,5 +1093,59 @@ INNER JOIN page
10921093

10931094
query.Sql.Should().Be(expected);
10941095
}
1096+
1097+
[Test]
1098+
public void ThrowMissingReferenceForSelectStatementForIncludedEntityWhenMissingInclude()
1099+
{
1100+
FluentActions.Invoking(() =>
1101+
{
1102+
Person person = Context.People.First();
1103+
1104+
Expression select = person
1105+
.Renters
1106+
.Where((Renter) =>
1107+
DateTime.Today.Between(Renter.StartDate, Renter.EndDate.GetValueOrDefault(DateTime.Today.AddDays(1))))
1108+
.Select(x => x.Unit)
1109+
.Expression;
1110+
}).Should().Throw<InvalidOperationException>().WithMessage(SubSonicErrorMessages.MissingTableReferenceFor.Format(typeof(Unit).Name));
1111+
}
1112+
1113+
[Test]
1114+
public void CanGenerateSelectStatementForIncludedEntity()
1115+
{
1116+
string expected = @"SELECT [T1].[ID], [T1].[Bedrooms] AS [NumberOfBedrooms], [T1].[StatusID], [T1].[RealEstatePropertyID]
1117+
FROM [dbo].[Renter] AS [T2]
1118+
INNER JOIN [dbo].[Unit] AS [T1]
1119+
ON ([T1].[ID] = [T2].[UnitID])
1120+
WHERE (([T2].[PersonID] = @personid_1) AND @dt_value_2 BETWEEN [T2].[StartDate] AND COALESCE([T2].[EndDate], @dt_value_3))";
1121+
1122+
Person person = Context.People.First();
1123+
1124+
Expression select = person
1125+
.Renters
1126+
.Where((Renter) =>
1127+
DateTime.Today.Between(Renter.StartDate, Renter.EndDate.GetValueOrDefault(DateTime.Today.AddDays(1))))
1128+
.Include(x => x.Unit)
1129+
.Select(x => x.Unit)
1130+
.Expression;
1131+
1132+
IDbQuery query = null;
1133+
1134+
var logging = Context.Instance.GetService<ISubSonicLogger<DbSelectPageExpression>>();
1135+
1136+
using (var perf = logging.Start("SQL Query Writer"))
1137+
{
1138+
FluentActions.Invoking(() =>
1139+
{
1140+
ISubSonicQueryProvider<Status> builder = Context.Instance.GetService<ISubSonicQueryProvider<Status>>();
1141+
1142+
query = builder.ToQuery(select);
1143+
}).Should().NotThrow();
1144+
}
1145+
1146+
query.Sql.Should().NotBeNullOrEmpty();
1147+
1148+
query.Sql.Should().Be(expected);
1149+
}
10951150
}
10961151
}

0 commit comments

Comments
 (0)