Skip to content
This repository was archived by the owner on Feb 1, 2025. It is now read-only.

Commit a6e0076

Browse files
committed
Fixed query filters support. For now query filters can use DbContext's properties.
1 parent 78f831a commit a6e0076

File tree

11 files changed

+344
-286
lines changed

11 files changed

+344
-286
lines changed

Source/LinqToDB.EntityFrameworkCore/ILinqToDBForEFTools.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,10 @@ public interface ILinqToDBForEFTools
7070
/// </summary>
7171
/// <param name="expression">EF.Core expression tree.</param>
7272
/// <param name="dc">LINQ To DB <see cref="IDataContext"/> instance.</param>
73+
/// <param name="ctx">Optional DbContext instance.</param>
7374
/// <param name="model">EF.Core data model instance.</param>
7475
/// <returns>Transformed expression.</returns>
75-
Expression TransformExpression(Expression expression, IDataContext dc, IModel model);
76+
Expression TransformExpression(Expression expression, IDataContext dc, DbContext ctx, IModel model);
7677

7778
/// <summary>
7879
/// Extracts <see cref="DbContext"/> instance from <see cref="IQueryable"/> object.

Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFTools.cs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -226,11 +226,12 @@ public static MappingSchema GetMappingSchema(IModel model,
226226
/// </summary>
227227
/// <param name="expression">EF.Core expression tree.</param>
228228
/// <param name="dc">LINQ To DB <see cref="IDataContext"/> instance.</param>
229+
/// <param name="ctx">Optional DbContext instance.</param>
229230
/// <param name="model">EF.Core data model instance.</param>
230231
/// <returns>Transformed expression.</returns>
231-
public static Expression TransformExpression(Expression expression, IDataContext dc, IModel model)
232+
public static Expression TransformExpression(Expression expression, IDataContext dc, DbContext ctx, IModel model)
232233
{
233-
return Implementation.TransformExpression(expression, dc, model);
234+
return Implementation.TransformExpression(expression, dc, ctx, model);
234235
}
235236

236237
/// <summary>
@@ -259,17 +260,17 @@ public static DataConnection CreateLinqToDbConnection(this DbContext context,
259260
{
260261
var dbTrasaction = transaction.GetDbTransaction();
261262
if (provider.IsCompatibleConnection(dbTrasaction.Connection))
262-
dc = new LinqToDBForEFToolsDataConnection(provider, dbTrasaction, context.Model, TransformExpression);
263+
dc = new LinqToDBForEFToolsDataConnection(context, provider, dbTrasaction, context.Model, TransformExpression);
263264
}
264265

265266
if (dc == null)
266267
{
267268
var dbConnection = context.Database.GetDbConnection();
268269
if (provider.IsCompatibleConnection(dbConnection))
269-
dc = new LinqToDBForEFToolsDataConnection(provider, dbConnection, context.Model, TransformExpression);
270+
dc = new LinqToDBForEFToolsDataConnection(context, provider, dbConnection, context.Model, TransformExpression);
270271
else
271272
{
272-
dc = new LinqToDBForEFToolsDataConnection(provider, connectionInfo.ConnectionString, context.Model, TransformExpression);
273+
dc = new LinqToDBForEFToolsDataConnection(context, provider, connectionInfo.ConnectionString, context.Model, TransformExpression);
273274
}
274275
}
275276

@@ -313,18 +314,18 @@ public static IDataContext CreateLinqToDbContext(this DbContext context,
313314
{
314315
var dbTransaction = transaction.GetDbTransaction();
315316
if (provider.IsCompatibleConnection(dbTransaction.Connection))
316-
dc = new LinqToDBForEFToolsDataConnection(provider, dbTransaction, context.Model, TransformExpression);
317+
dc = new LinqToDBForEFToolsDataConnection(context, provider, dbTransaction, context.Model, TransformExpression);
317318
}
318319

319320
if (dc == null)
320321
{
321322
var dbConnection = context.Database.GetDbConnection();
322323
if (provider.IsCompatibleConnection(dbConnection))
323-
dc = new LinqToDBForEFToolsDataConnection(provider, context.Database.GetDbConnection(), context.Model, TransformExpression);
324+
dc = new LinqToDBForEFToolsDataConnection(context, provider, context.Database.GetDbConnection(), context.Model, TransformExpression);
324325
else
325326
{
326327
// special case when we have to create data connection by itself
327-
var dataContext = new LinqToDBForEFToolsDataContext(provider, connectionInfo.ConnectionString, context.Model, TransformExpression);
328+
var dataContext = new LinqToDBForEFToolsDataContext(context, provider, connectionInfo.ConnectionString, context.Model, TransformExpression);
328329

329330
if (mappingSchema != null)
330331
dataContext.MappingSchema = mappingSchema;
@@ -359,7 +360,7 @@ public static DataConnection CreateLinq2DbConnectionDetached([JetBrains.Annotati
359360
var connectionInfo = GetConnectionInfo(info);
360361
var dataProvider = GetDataProvider(info, connectionInfo);
361362

362-
var dc = new LinqToDBForEFToolsDataConnection(dataProvider, connectionInfo.ConnectionString, context.Model, TransformExpression);
363+
var dc = new LinqToDBForEFToolsDataConnection(context, dataProvider, connectionInfo.ConnectionString, context.Model, TransformExpression);
363364
var logger = CreateLogger(info.Options);
364365
if (logger != null)
365366
dc.OnTraceConnection = t => Implementation.LogConnectionTrace(t, logger);
@@ -424,9 +425,9 @@ public static DataConnection CreateLinqToDbConnection(this DbContextOptions opti
424425
var model = GetModel(options);
425426

426427
if (connectionInfo.Connection != null)
427-
dc = new LinqToDBForEFToolsDataConnection(dataProvider, connectionInfo.Connection, model, TransformExpression);
428+
dc = new LinqToDBForEFToolsDataConnection(null, dataProvider, connectionInfo.Connection, model, TransformExpression);
428429
else if (connectionInfo.ConnectionString != null)
429-
dc = new LinqToDBForEFToolsDataConnection(dataProvider, connectionInfo.ConnectionString, model, TransformExpression);
430+
dc = new LinqToDBForEFToolsDataConnection(null, dataProvider, connectionInfo.ConnectionString, model, TransformExpression);
430431

431432
if (dc == null)
432433
throw new LinqToDBForEFToolsException($"Can not extract connection information from {nameof(DbContextOptions)}");

Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFToolsDataConnection.cs

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using Microsoft.EntityFrameworkCore.Metadata;
66

77
using JetBrains.Annotations;
8+
using Microsoft.EntityFrameworkCore;
89

910
namespace LinqToDB.EntityFrameworkCore
1011
{
@@ -15,45 +16,52 @@ namespace LinqToDB.EntityFrameworkCore
1516

1617
public class LinqToDBForEFToolsDataConnection : DataConnection, IExpressionPreprocessor
1718
{
19+
readonly DbContext _context;
1820
readonly IModel _model;
19-
readonly Func<Expression, IDataContext, IModel, Expression> _transformFunc;
21+
readonly Func<Expression, IDataContext, DbContext, IModel, Expression> _transformFunc;
2022

2123
public LinqToDBForEFToolsDataConnection(
22-
[NotNull] IDataProvider dataProvider,
23-
[NotNull] string connectionString,
24-
IModel model,
25-
Func<Expression, IDataContext, IModel, Expression> transformFunc) : base(dataProvider, connectionString)
24+
[CanBeNull] DbContext context,
25+
[NotNull] IDataProvider dataProvider,
26+
[NotNull] string connectionString,
27+
IModel model,
28+
Func<Expression, IDataContext, DbContext, IModel, Expression> transformFunc) : base(dataProvider, connectionString)
2629
{
27-
_model = model;
30+
_context = context;
31+
_model = model;
2832
_transformFunc = transformFunc;
2933
}
3034

3135
public LinqToDBForEFToolsDataConnection(
32-
[NotNull] IDataProvider dataProvider,
33-
[NotNull] IDbTransaction transaction,
34-
IModel model,
35-
Func<Expression, IDataContext, IModel, Expression> transformFunc
36+
[CanBeNull] DbContext context,
37+
[NotNull] IDataProvider dataProvider,
38+
[NotNull] IDbTransaction transaction,
39+
IModel model,
40+
Func<Expression, IDataContext, DbContext, IModel, Expression> transformFunc
3641
) : base(dataProvider, transaction)
3742
{
38-
_model = model;
43+
_context = context;
44+
_model = model;
3945
_transformFunc = transformFunc;
4046
}
4147

4248
public LinqToDBForEFToolsDataConnection(
43-
[NotNull] IDataProvider dataProvider,
44-
[NotNull] IDbConnection connection,
45-
IModel model,
46-
Func<Expression, IDataContext, IModel, Expression> transformFunc) : base(dataProvider, connection)
49+
[CanBeNull] DbContext context,
50+
[NotNull] IDataProvider dataProvider,
51+
[NotNull] IDbConnection connection,
52+
IModel model,
53+
Func<Expression, IDataContext, DbContext, IModel, Expression> transformFunc) : base(dataProvider, connection)
4754
{
48-
_model = model;
55+
_context = context;
56+
_model = model;
4957
_transformFunc = transformFunc;
5058
}
5159

5260
public Expression ProcessExpression(Expression expression)
5361
{
5462
if (_transformFunc == null)
5563
return expression;
56-
return _transformFunc(expression, this, _model);
64+
return _transformFunc(expression, this, _context, _model);
5765
}
5866
}
5967
}

Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFToolsDataContext.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using Microsoft.EntityFrameworkCore.Metadata;
55

66
using JetBrains.Annotations;
7+
using Microsoft.EntityFrameworkCore;
78

89
namespace LinqToDB.EntityFrameworkCore
910
{
@@ -13,24 +14,28 @@ namespace LinqToDB.EntityFrameworkCore
1314

1415
public class LinqToDBForEFToolsDataContext : DataContext, IExpressionPreprocessor
1516
{
17+
[CanBeNull]
18+
readonly DbContext _context;
1619
readonly IModel _model;
17-
readonly Func<Expression, IDataContext, IModel, Expression> _transformFunc;
20+
readonly Func<Expression, IDataContext, DbContext, IModel, Expression> _transformFunc;
1821

1922
public LinqToDBForEFToolsDataContext(
20-
[NotNull] IDataProvider dataProvider,
21-
[NotNull] string connectionString,
22-
IModel model,
23-
Func<Expression, IDataContext, IModel, Expression> transformFunc) : base(dataProvider, connectionString)
23+
[CanBeNull] DbContext context,
24+
[NotNull] IDataProvider dataProvider,
25+
[NotNull] string connectionString,
26+
IModel model,
27+
Func<Expression, IDataContext, DbContext, IModel, Expression> transformFunc) : base(dataProvider, connectionString)
2428
{
25-
_model = model;
29+
_context = context;
30+
_model = model;
2631
_transformFunc = transformFunc;
2732
}
2833

2934
public Expression ProcessExpression(Expression expression)
3035
{
3136
if (_transformFunc == null)
3237
return expression;
33-
return _transformFunc(expression, this, _model);
38+
return _transformFunc(expression, this, _context, _model);
3439
}
3540

3641
}

Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFToolsImplDefault.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,10 +584,11 @@ static List<Expression> CompactTree(List<Expression> items, ExpressionType nodeT
584584
/// </summary>
585585
/// <param name="expression">EF.Core expression tree.</param>
586586
/// <param name="dc">LINQ To DB <see cref="IDataContext"/> instance.</param>
587+
/// <param name="ctx">Optional DbContext instance.</param>
587588
/// <param name="model">EF.Core data model instance.</param>
588589
/// <returns>Transformed expression.</returns>
589590
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "EF1001:Internal EF Core API usage.", Justification = "<Pending>")]
590-
public virtual Expression TransformExpression(Expression expression, IDataContext dc, IModel model)
591+
public virtual Expression TransformExpression(Expression expression, IDataContext dc, DbContext ctx, IModel model)
591592
{
592593
var ignoreQueryFilters = false;
593594

@@ -685,6 +686,24 @@ Expression LocalTransform(Expression e)
685686
if (filter != null)
686687
{
687688
var filterBody = filter.Body.Transform(l => LocalTransform(l));
689+
690+
// replacing DbContext constant
691+
if (ctx != null)
692+
{
693+
filterBody = filterBody.Transform(fe =>
694+
{
695+
if (fe.NodeType == ExpressionType.Constant)
696+
{
697+
if (fe.Type.IsAssignableFrom(ctx.GetType()))
698+
{
699+
return Expression.Constant(ctx, fe.Type);
700+
}
701+
}
702+
703+
return fe;
704+
});
705+
}
706+
688707
filter = Expression.Lambda(filterBody, filter.Parameters[0]);
689708
var whereExpr = Expression.Call(null, WhereMethodInfo.MakeGenericMethod(entityType), newExpr, Expression.Quote(filter));
690709

Source/LinqToDB.EntityFrameworkCore/linq2db.EntityFrameworkCore.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
</PropertyGroup>
1010

1111
<ItemGroup>
12-
<PackageReference Include="linq2db" Version="2.9.5" />
12+
<PackageReference Include="linq2db" Version="2.9.6" />
1313
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.0.0" />
1414
</ItemGroup>
1515

Tests/LinqToDB.EntityFrameworkCore.Tests/LinqToDB.EntityFrameworkCore.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
<ItemGroup>
1414
<PackageReference Include="JetBrains.DotMemoryUnit" Version="3.0.20171219.105559" />
15-
<PackageReference Include="linq2db" Version="2.9.5" />
15+
<PackageReference Include="linq2db" Version="2.9.6" />
1616
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="3.0.0" />
1717
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.0.0" />
1818
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0" />

0 commit comments

Comments
 (0)