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

Commit 53f9356

Browse files
authored
Merge pull request #75 from linq2db/master
Release 5.0.0
2 parents 904f047 + e78cda4 commit 53f9356

24 files changed

+411
-139
lines changed

Build/linq2db.Default.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project>
22
<PropertyGroup>
3-
<Version>3.7.0</Version>
3+
<Version>5.0.0</Version>
44

55
<Description>Allows to execute Linq to DB (linq2db) queries in Entity Framework Core DbContext.</Description>
66
<Title>Linq to DB (linq2db) extensions for Entity Framework Core</Title>

Build/linq2db.Tests.props

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<Project>
2+
<PropertyGroup>
3+
<!--<TargetFrameworks>net5.0</TargetFrameworks>-->
4+
<TargetFrameworks>netcoreapp3.1</TargetFrameworks>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.0" />
9+
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0">
10+
<PrivateAssets>all</PrivateAssets>
11+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
12+
</PackageReference>
13+
<PackageReference Include="NUnit" Version="3.12.0" />
14+
</ItemGroup>
15+
16+
</Project>

NuGet/linq2db.EntityFrameworkCore.nuspec

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,17 @@
1414
<projectUrl>https://github.com/linq2db/linq2db.EntityFrameworkCore</projectUrl>
1515
<license type="file">MIT-LICENSE.txt</license>
1616
<dependencies>
17-
<group targetFramework=".NETStandard2.0">
18-
<dependency id="Microsoft.EntityFrameworkCore.Relational" version="3.1.3" />
19-
<dependency id="linq2db" version="3.1.5" />
17+
<group targetFramework=".NETStandard2.1">
18+
<dependency id="Microsoft.EntityFrameworkCore.Relational" version="5.0.0" />
19+
<dependency id="linq2db" version="3.1.6" />
2020
</group>
2121
</dependencies>
2222
</metadata>
2323

2424
<files>
25-
<file src="..\Source\LinqToDB.EntityFrameworkCore\bin\Release\**\linq2db.EntityFrameworkCore.pdb" target="lib\" />
26-
<file src="..\Source\LinqToDB.EntityFrameworkCore\bin\Release\**\linq2db.EntityFrameworkCore.xml" target="lib\" />
27-
<file src="..\Source\LinqToDB.EntityFrameworkCore\bin\Release\**\linq2db.EntityFrameworkCore.dll" target="lib\" />
25+
<file src="..\Source\LinqToDB.EntityFrameworkCore\bin\Release\netstandard2.1\linq2db.EntityFrameworkCore.pdb" target="lib\" />
26+
<file src="..\Source\LinqToDB.EntityFrameworkCore\bin\Release\netstandard2.1\linq2db.EntityFrameworkCore.xml" target="lib\" />
27+
<file src="..\Source\LinqToDB.EntityFrameworkCore\bin\Release\netstandard2.1\linq2db.EntityFrameworkCore.dll" target="lib\" />
2828

2929
<file src="..\MIT-LICENSE.txt" />
3030

Source/LinqToDB.EntityFrameworkCore/EFCoreMetadataReader.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using LinqToDB.Expressions;
88
using LinqToDB.Reflection;
99
using Microsoft.EntityFrameworkCore;
10+
using Microsoft.EntityFrameworkCore.Diagnostics;
1011
using Microsoft.EntityFrameworkCore.Metadata;
1112
using Microsoft.EntityFrameworkCore.Metadata.Internal;
1213
using Microsoft.EntityFrameworkCore.Query;
@@ -32,12 +33,18 @@ internal class EFCoreMetadataReader : IMetadataReader
3233
private readonly RelationalSqlTranslatingExpressionVisitorDependencies _dependencies;
3334
private readonly IRelationalTypeMappingSource _mappingSource;
3435
private readonly ConcurrentDictionary<MemberInfo, EFCoreExpressionAttribute> _calculatedExtensions = new ConcurrentDictionary<MemberInfo, EFCoreExpressionAttribute>();
36+
private readonly IDiagnosticsLogger<DbLoggerCategory.Query> _logger;
3537

36-
public EFCoreMetadataReader(IModel model, RelationalSqlTranslatingExpressionVisitorDependencies dependencies, IRelationalTypeMappingSource mappingSource)
38+
public EFCoreMetadataReader(IModel model,
39+
RelationalSqlTranslatingExpressionVisitorDependencies dependencies,
40+
IRelationalTypeMappingSource mappingSource,
41+
IDiagnosticsLogger<DbLoggerCategory.Query> logger
42+
)
3743
{
3844
_model = model;
3945
_dependencies = dependencies;
4046
_mappingSource = mappingSource;
47+
_logger = logger;
4148
}
4249

4350
public T[] GetAttributes<T>(Type type, bool inherit = true) where T : Attribute
@@ -189,7 +196,7 @@ public T[] GetAttributes<T>(Type type, MemberInfo memberInfo, bool inherit = tru
189196
foreach (var navigation in navigations)
190197
{
191198
var fk = navigation.ForeignKey;
192-
if (fk.PrincipalEntityType == et)
199+
if (!navigation.IsOnDependent)
193200
{
194201
var thisKey = string.Join(",", fk.PrincipalKey.Properties.Select(p => p.Name));
195202
var otherKey = string.Join(",", fk.Properties.Select(p => p.Name));
@@ -312,7 +319,7 @@ public SqlTransparentExpression(Expression expression, RelationalTypeMapping typ
312319
Expression = expression;
313320
}
314321

315-
public override void Print(ExpressionPrinter expressionPrinter)
322+
protected override void Print(ExpressionPrinter expressionPrinter)
316323
{
317324
expressionPrinter.Print(Expression);
318325
}
@@ -341,7 +348,7 @@ private Sql.ExpressionAttribute GetDbFunctionFromMethodCall(Type type, MethodInf
341348
Expression.Constant(DefaultValue.GetValue(p.ParameterType), p.ParameterType),
342349
_mappingSource?.FindMapping(p.ParameterType))).ToArray();
343350

344-
var newExpression = _dependencies.MethodCallTranslatorProvider.Translate(_model, objExpr, methodInfo, parametersArray);
351+
var newExpression = _dependencies.MethodCallTranslatorProvider.Translate(_model, objExpr, methodInfo, parametersArray, _logger);
345352
if (newExpression != null)
346353
{
347354
if (!methodInfo.IsStatic)
@@ -374,7 +381,7 @@ private Sql.ExpressionAttribute GetDbFunctionFromProperty(Type type, PropertyInf
374381
{
375382
var objExpr = new SqlTransparentExpression(Expression.Constant(DefaultValue.GetValue(type), type), _mappingSource?.FindMapping(propInfo));
376383

377-
var newExpression = _dependencies.MemberTranslatorProvider.Translate(objExpr, propInfo, propInfo.GetMemberType());
384+
var newExpression = _dependencies.MemberTranslatorProvider.Translate(objExpr, propInfo, propInfo.GetMemberType(), _logger);
378385
if (newExpression != null)
379386
{
380387
var parametersArray = new Expression[] { objExpr };

Source/LinqToDB.EntityFrameworkCore/ILinqToDBForEFTools.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Linq.Expressions;
33

44
using Microsoft.EntityFrameworkCore;
5+
using Microsoft.EntityFrameworkCore.Diagnostics;
56
using Microsoft.EntityFrameworkCore.Infrastructure;
67
using Microsoft.EntityFrameworkCore.Metadata;
78
using Microsoft.EntityFrameworkCore.Query;
@@ -40,8 +41,11 @@ public interface ILinqToDBForEFTools
4041
/// <param name="model">EF.Core data model.</param>
4142
/// <param name="dependencies"></param>
4243
/// <param name="mappingSource"></param>
44+
/// <param name="logger"></param>
4345
/// <returns>LINQ To DB metadata provider for specified EF.Core model. Can return <c>null</c>.</returns>
44-
IMetadataReader CreateMetadataReader(IModel model, RelationalSqlTranslatingExpressionVisitorDependencies dependencies, IRelationalTypeMappingSource mappingSource);
46+
IMetadataReader CreateMetadataReader(IModel model, RelationalSqlTranslatingExpressionVisitorDependencies dependencies,
47+
IRelationalTypeMappingSource mappingSource,
48+
IDiagnosticsLogger<DbLoggerCategory.Query> logger);
4549

4650
/// <summary>
4751
/// Creates mapping schema using provided EF.Core data model and metadata provider.

Source/LinqToDB.EntityFrameworkCore/Internal/LinqToDBForEFQueryProvider.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Threading;
88
using System.Threading.Tasks;
99

10+
using Microsoft.EntityFrameworkCore.Query;
1011
using Microsoft.EntityFrameworkCore.Query.Internal;
1112

1213
using JetBrains.Annotations;

Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFTools.cs

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Concurrent;
33
using System.Data.Common;
4+
using System.Diagnostics;
45
using System.Linq;
56
using System.Linq.Expressions;
67
using System.Reflection;
@@ -11,6 +12,7 @@
1112
using Microsoft.Extensions.Logging;
1213

1314
using JetBrains.Annotations;
15+
using Microsoft.EntityFrameworkCore.Diagnostics;
1416
using Microsoft.EntityFrameworkCore.Query;
1517
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
1618

@@ -93,7 +95,7 @@ public static ILinqToDBForEFTools Implementation
9395
{
9496
_implementation = value ?? throw new ArgumentNullException(nameof(value));
9597
_metadataReaders.Clear();
96-
_defaultMetadataReader = new Lazy<IMetadataReader>(() => Implementation.CreateMetadataReader(null, null, null));
98+
_defaultMetadataReader = new Lazy<IMetadataReader>(() => Implementation.CreateMetadataReader(null, null, null, null));
9799
}
98100
}
99101

@@ -124,14 +126,15 @@ static LinqToDBForEFTools()
124126
/// <param name="model">EF.Core data model instance. Could be <c>null</c>.</param>
125127
/// <param name="dependencies"></param>
126128
/// <param name="mappingSource"></param>
129+
/// <param name="logger"></param>
127130
/// <returns>LINQ To DB metadata provider.</returns>
128131
public static IMetadataReader GetMetadataReader([JetBrains.Annotations.CanBeNull] IModel model,
129-
RelationalSqlTranslatingExpressionVisitorDependencies dependencies, IRelationalTypeMappingSource mappingSource)
132+
RelationalSqlTranslatingExpressionVisitorDependencies dependencies, IRelationalTypeMappingSource mappingSource, IDiagnosticsLogger<DbLoggerCategory.Query> logger)
130133
{
131134
if (model == null)
132135
return _defaultMetadataReader.Value;
133136

134-
return _metadataReaders.GetOrAdd(model, m => Implementation.CreateMetadataReader(model, dependencies, mappingSource));
137+
return _metadataReaders.GetOrAdd(model, m => Implementation.CreateMetadataReader(model, dependencies, mappingSource, logger));
135138
}
136139

137140
/// <summary>
@@ -218,13 +221,15 @@ public static IDataProvider GetDataProvider(EFProviderInfo info, EFConnectionInf
218221
/// <param name="convertorSelector">EF Core registry for type conversion.</param>
219222
/// <param name="dependencies"></param>
220223
/// <param name="mappingSource"></param>
224+
/// <param name="logger"></param>
221225
/// <returns>Mapping schema for provided EF.Core model.</returns>
222226
public static MappingSchema GetMappingSchema(IModel model,
223227
IValueConverterSelector convertorSelector,
224228
RelationalSqlTranslatingExpressionVisitorDependencies dependencies,
225-
IRelationalTypeMappingSource mappingSource)
229+
IRelationalTypeMappingSource mappingSource,
230+
IDiagnosticsLogger<DbLoggerCategory.Query> logger)
226231
{
227-
return Implementation.GetMappingSchema(model, GetMetadataReader(model, dependencies, mappingSource), convertorSelector);
232+
return Implementation.GetMappingSchema(model, GetMetadataReader(model, dependencies, mappingSource, logger), convertorSelector);
228233
}
229234

230235
/// <summary>
@@ -284,18 +289,30 @@ public static DataConnection CreateLinqToDbConnection(this DbContext context,
284289

285290
var logger = CreateLogger(info.Options);
286291
if (logger != null)
287-
dc.OnTraceConnection = t => Implementation.LogConnectionTrace(t, logger);
292+
{
293+
EnableTracing(dc, logger);
294+
}
288295

289296
var dependencies = context.GetService<RelationalSqlTranslatingExpressionVisitorDependencies>();
290297
var mappingSource = context.GetService<IRelationalTypeMappingSource>();
291298
var converters = context.GetService<IValueConverterSelector>();
292-
var mappingSchema = GetMappingSchema(context.Model, converters, dependencies, mappingSource);
299+
var dLogger = context.GetService<IDiagnosticsLogger<DbLoggerCategory.Query>>();
300+
var mappingSchema = GetMappingSchema(context.Model, converters, dependencies, mappingSource, dLogger);
293301
if (mappingSchema != null)
294302
dc.AddMappingSchema(mappingSchema);
295303

296304
return dc;
297305
}
298306

307+
private static TraceSwitch _defaultTraceSwitch =
308+
new TraceSwitch("DataConnection", "DataConnection trace switch", TraceLevel.Info.ToString());
309+
310+
static void EnableTracing(DataConnection dc, ILogger logger)
311+
{
312+
dc.OnTraceConnection = t => Implementation.LogConnectionTrace(t, logger);
313+
dc.TraceSwitchConnection = _defaultTraceSwitch;
314+
}
315+
299316
public static ILogger CreateLogger(IDbContextOptions options)
300317
{
301318
return Implementation.CreateLogger(options);
@@ -317,7 +334,8 @@ public static IDataContext CreateLinqToDbContext(this DbContext context,
317334
var dependencies = context.GetService<RelationalSqlTranslatingExpressionVisitorDependencies>();
318335
var mappingSource = context.GetService<IRelationalTypeMappingSource>();
319336
var converters = context.GetService<IValueConverterSelector>();
320-
var mappingSchema = GetMappingSchema(context.Model, converters, dependencies, mappingSource);
337+
var dLogger = context.GetService<IDiagnosticsLogger<DbLoggerCategory.Query>>();
338+
var mappingSchema = GetMappingSchema(context.Model, converters, dependencies, mappingSource, dLogger);
321339
var logger = CreateLogger(info.Options);
322340

323341
if (transaction != null)
@@ -356,7 +374,9 @@ public static IDataContext CreateLinqToDbContext(this DbContext context,
356374
dc.AddMappingSchema(mappingSchema);
357375

358376
if (logger != null)
359-
dc.OnTraceConnection = t => Implementation.LogConnectionTrace(t, logger);
377+
{
378+
EnableTracing(dc, logger);
379+
}
360380

361381
return dc;
362382
}
@@ -377,13 +397,17 @@ public static DataConnection CreateLinq2DbConnectionDetached([JetBrains.Annotati
377397

378398
var dc = new LinqToDBForEFToolsDataConnection(context, dataProvider, connectionInfo.ConnectionString, context.Model, TransformExpression);
379399
var logger = CreateLogger(info.Options);
400+
380401
if (logger != null)
381-
dc.OnTraceConnection = t => Implementation.LogConnectionTrace(t, logger);
402+
{
403+
EnableTracing(dc, logger);
404+
}
382405

383406
var dependencies = context.GetService<RelationalSqlTranslatingExpressionVisitorDependencies>();
384407
var mappingSource = context.GetService<IRelationalTypeMappingSource>();
385408
var converters = context.GetService<IValueConverterSelector>();
386-
var mappingSchema = GetMappingSchema(context.Model, converters, dependencies, mappingSource);
409+
var dLogger = context.GetService<IDiagnosticsLogger<DbLoggerCategory.Query>>();
410+
var mappingSchema = GetMappingSchema(context.Model, converters, dependencies, mappingSource, dLogger);
387411
if (mappingSchema != null)
388412
dc.AddMappingSchema(mappingSchema);
389413

@@ -472,11 +496,13 @@ public static DataConnection CreateLinqToDbConnection(this DbContextOptions opti
472496

473497
var logger = CreateLogger(info.Options);
474498
if (logger != null)
475-
dc.OnTraceConnection = t => Implementation.LogConnectionTrace(t, logger);
499+
{
500+
EnableTracing(dc, logger);
501+
}
476502

477503
if (model != null)
478504
{
479-
var mappingSchema = GetMappingSchema(model, null, null, null);
505+
var mappingSchema = GetMappingSchema(model, null, null, null, null);
480506
if (mappingSchema != null)
481507
dc.AddMappingSchema(mappingSchema);
482508
}

0 commit comments

Comments
 (0)