Skip to content

Commit 448c6b2

Browse files
Fix Single Type Reference for Where clause, Added Test cases
1 parent cb33ae8 commit 448c6b2

4 files changed

Lines changed: 103 additions & 1 deletion

File tree

FluentSql.Tests/SelectStatement/SelectStatementTest.cs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,26 @@ public void GetSelectQueryWithJoin2()
381381
Xunit.Assert.IsType<Employee>(employeeSet.FirstOrDefault());
382382
}
383383

384+
[Fact]
385+
public void GetSelectQueryWith4Joins()
386+
{
387+
var store = new EntityStore(_dbConnection);
388+
var startingOrderDate = new DateTime(2015, 12, 1);
389+
var selectQuery = store.GetSelectQuery<Employee>()
390+
.JoinOn<Order>((e, o) => e.Id == o.EmployeeId && o.Id >= 1)
391+
.JoinOn<Order, Customer>((o, c) => o.CustomerId == c.Id)
392+
.JoinOn<Order, OrderDetail>((o, od) => o.Id == od.OrderId)
393+
.Where<Order, Customer, OrderDetail, Employee>((o, c, od, e) => o.OrderDate > startingOrderDate
394+
&& c.City == "Gainesville" && e.Id >= 1 && od.Quantity > 1)
395+
.OrderBy(e => e.Username);
396+
397+
var employeeSet = store.ExecuteQuery(selectQuery);
398+
399+
Xunit.Assert.NotNull(employeeSet);
400+
Xunit.Assert.True(employeeSet.Count() >= 2);
401+
Xunit.Assert.IsType<Employee>(employeeSet.FirstOrDefault());
402+
}
403+
384404
[Fact]
385405
public void GetSelectQueryWithJoin3()
386406
{
@@ -416,6 +436,24 @@ public async void GetSelectQueryWithJoin2Async()
416436
Xunit.Assert.IsType<Employee>(employeeSet.FirstOrDefault());
417437
}
418438

439+
[Fact]
440+
public async void GetSelectQueryWithOneWhereTypeReferenceAsync()
441+
{
442+
var store = new EntityStore(_dbConnection);
443+
var startingOrderDate = new DateTime(2015, 12, 1);
444+
var selectQuery = store.GetSelectQuery<Employee>()
445+
.JoinOn<Order>((e, o) => e.Id == o.EmployeeId && o.Id >= 1)
446+
.JoinOn<Order, Customer>((o, c) => o.CustomerId == c.Id)
447+
.Where<Order>(o => o.OrderDate > startingOrderDate)
448+
.OrderBy(e => e.Username);
449+
450+
var employeeSet = await store.ExecuteQueryAsync(selectQuery);
451+
452+
Xunit.Assert.NotNull(employeeSet);
453+
Xunit.Assert.True(employeeSet.Count() >= 2);
454+
Xunit.Assert.IsType<Employee>(employeeSet.FirstOrDefault());
455+
}
456+
419457
[Fact]
420458
public void GetSelectQueryWithLeftJoin()
421459
{
@@ -829,6 +867,7 @@ public void WhereClauseWithGetDatePartWeek()
829867
var singleEmployee = store.GetSingle<Employee>(e => SqlFunctions.GetWeek(e.Birthdate) >= 5);
830868

831869
Xunit.Assert.NotNull(singleEmployee);
870+
832871
}
833872

834873
[Fact]
@@ -876,6 +915,20 @@ public void WhereClauseWithGetDatePartMillisecond()
876915
Xunit.Assert.NotNull(singleEmployee);
877916
}
878917

918+
[Fact]
919+
public void WhereClauseThrowsException()
920+
{
921+
var store = new EntityStore(_dbConnection);
922+
string NO_DATETIME_SUPPORT = "SqlFunction does not support DateTime functions or variables. It supports DateTime Entity Types";
923+
924+
var singleEmployee = store.GetSingle<Order>(o => SqlFunctions.GetMillisecond(o.OrderDate) >= 0);
925+
926+
var ex = Xunit.Assert.Throws<Exception>(()
927+
=> store.GetSingle<Order>(o => SqlFunctions.GetMillisecond(DateTime.Now) >= 0));
928+
929+
Xunit.Assert.Equal(NO_DATETIME_SUPPORT, ex.Message);
930+
}
931+
879932
public void Dispose()
880933
{
881934
_dbConnection.Close();

FluentSql/SqlGenerators/IQuery.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,21 @@ public interface IQuery<L> : IToSql
3333

3434
IQuery<L> Where(Expression<Func<L, bool>> expression);
3535

36+
IQuery<L> Where<T>(Expression<Func<T, bool>> expression) where T : new();
37+
3638
IQuery<L> Where<T1, T2>(Expression<Func<T1, T2, bool>> expression) where T1 : new() where T2 : new();
3739

3840
IQuery<L> Where<T1, T2, T3>(Expression<Func<T1, T2, T3, bool>> expression)
3941
where T1 : new()
4042
where T2 : new()
4143
where T3 : new();
4244

45+
IQuery<L> Where<T1, T2, T3, T4>(Expression<Func<T1, T2, T3, T4, bool>> expression)
46+
where T1 : new()
47+
where T2 : new()
48+
where T3 : new()
49+
where T4 : new();
50+
4351
IQuery<L> GetTopRows(int topNumberOfRows);
4452

4553
IQuery<L> OrderBy(Expression<Func<L, object>> expression);

FluentSql/SqlGenerators/Query.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,20 @@ public virtual IQuery<TEntity> Where(Expression<Func<TEntity, bool>> expression)
9393
return this;
9494
}
9595

96+
public IQuery<TEntity> Where<T>(Expression<Func<T, bool>> expression) where T : new()
97+
{
98+
if (expression == null) return this;
99+
100+
Predicate = new ExpressionHelper(expression, ParameterNameGenerator);
101+
102+
if (Parameters.ParameterNames.Any())
103+
Parameters.AddDynamicParams(Predicate.QueryParameters);
104+
else
105+
Parameters = Predicate.QueryParameters;
106+
107+
return this;
108+
}
109+
96110
public IQuery<TEntity> Where<T1, T2>(Expression<Func<T1, T2, bool>> expression) where T1 : new() where T2 : new()
97111
{
98112
if (expression == null) return this;
@@ -124,6 +138,25 @@ public IQuery<TEntity> Where<T1, T2, T3>(Expression<Func<T1, T2, T3, bool>> expr
124138
return this;
125139
}
126140

141+
142+
public IQuery<TEntity> Where<T1, T2, T3, T4>(Expression<Func<T1, T2, T3, T4, bool>> expression)
143+
where T1 : new()
144+
where T2 : new()
145+
where T3 : new()
146+
where T4 : new()
147+
{
148+
if (expression == null) return this;
149+
150+
Predicate = new ExpressionHelper(expression, ParameterNameGenerator);
151+
152+
if (Parameters.ParameterNames.Any())
153+
Parameters.AddDynamicParams(Predicate.QueryParameters);
154+
else
155+
Parameters = Predicate.QueryParameters;
156+
157+
return this;
158+
}
159+
127160
internal IQuery<TEntity> Where(string leftOperand, ExpressionType predicateOperator, string rightOperand, bool isParametized = false, ExpressionType? linkingOperator = null)
128161
{
129162
if (this.PredicateParts == null)

FluentSql/Support/Helpers/ExpressionHelper.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ public ExpressionHelper(Expression predicateExpression, SqlGeneratorHelper param
2626
}
2727
#endregion
2828

29+
#region Constants
30+
private readonly string NO_DATETIME_SUPPORT = "SqlFunction does not support DateTime functions or variables. It supports DateTime Entity Types";
31+
#endregion
32+
2933
#region Private Properties
3034
private static readonly char[] _period = new char[] { '.' };
3135
private IComparer<ExpressionType> _comparer = new OperatorPrecedenceComparer();
@@ -481,6 +485,10 @@ private MethodCallExpression ParseSqlFunctions(MethodCallExpression methodCall)
481485
throw new Exception(string.Format("Method not implemented: {0}", methodName ?? "Undetermined method name."));
482486

483487
var fieldTypeExpression = methodCall.Arguments[0];
488+
489+
if (fieldTypeExpression.NodeType == ExpressionType.Convert)
490+
throw new Exception(NO_DATETIME_SUPPORT);
491+
484492
var functionArgument = methodCall.Arguments[1];
485493
var memberExpression = (MemberExpression)fieldTypeExpression;
486494

@@ -512,7 +520,7 @@ private MethodCallExpression ParseSqlFunctions(MethodCallExpression methodCall)
512520
GetDateOperands(methodCall, 0, ref operandType, ref operand);
513521

514522
if (operandType == typeof(DateTime) || operandType == typeof(DateTime?))
515-
throw new Exception("Expression Helper does not support DateTime functions or variables. It supports DateTime Entity Types");
523+
throw new Exception(NO_DATETIME_SUPPORT);
516524

517525
var datePartFuntion = EntityMapper.SqlGenerator.GetDatePartFunction(methodName, operandType, operand);
518526

0 commit comments

Comments
 (0)