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

Commit 1b956ad

Browse files
authored
Merge pull request #76 from linq2db/version3
Release 3.8.0
2 parents 904f047 + 3688e3b commit 1b956ad

File tree

19 files changed

+320
-74
lines changed

19 files changed

+320
-74
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>3.8.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>

NuGet/linq2db.EntityFrameworkCore.nuspec

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
33
<metadata>
44
<id>linq2db.EntityFrameworkCore</id>
5-
<title>Linq to DB (linq2db) extensions for Entity Framework Core</title>
5+
<title>Linq to DB (linq2db) extensions for Entity Framework Core 3.1</title>
66
<authors>Igor Tkachev, Ilya Chudin, Svyatoslav Danyliv, Dmitry Lukashenko</authors>
77
<owners>Igor Tkachev, Ilya Chudin, Svyatoslav Danyliv, Dmitry Lukashenko</owners>
88
<copyright>Copyright © 2020 Igor Tkachev, Ilya Chudin, Svyatoslav Danyliv, Dmitry Lukashenko</copyright>
@@ -15,8 +15,8 @@
1515
<license type="file">MIT-LICENSE.txt</license>
1616
<dependencies>
1717
<group targetFramework=".NETStandard2.0">
18-
<dependency id="Microsoft.EntityFrameworkCore.Relational" version="3.1.3" />
19-
<dependency id="linq2db" version="3.1.5" />
18+
<dependency id="Microsoft.EntityFrameworkCore.Relational" version="3.1.10" />
19+
<dependency id="linq2db" version="3.1.6" />
2020
</group>
2121
</dependencies>
2222
</metadata>

Source/LinqToDB.EntityFrameworkCore/EFCoreMetadataReader.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ public T[] GetAttributes<T>(Type type, MemberInfo memberInfo, bool inherit = tru
189189
foreach (var navigation in navigations)
190190
{
191191
var fk = navigation.ForeignKey;
192-
if (fk.PrincipalEntityType == et)
192+
if (!navigation.IsDependentToPrincipal())
193193
{
194194
var thisKey = string.Join(",", fk.PrincipalKey.Properties.Select(p => p.Name));
195195
var otherKey = string.Join(",", fk.Properties.Select(p => p.Name));

Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFTools.cs

Lines changed: 23 additions & 4 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;
@@ -284,7 +285,9 @@ public static DataConnection CreateLinqToDbConnection(this DbContext context,
284285

285286
var logger = CreateLogger(info.Options);
286287
if (logger != null)
287-
dc.OnTraceConnection = t => Implementation.LogConnectionTrace(t, logger);
288+
{
289+
EnableTracing(dc, logger);
290+
}
288291

289292
var dependencies = context.GetService<RelationalSqlTranslatingExpressionVisitorDependencies>();
290293
var mappingSource = context.GetService<IRelationalTypeMappingSource>();
@@ -296,6 +299,15 @@ public static DataConnection CreateLinqToDbConnection(this DbContext context,
296299
return dc;
297300
}
298301

302+
private static TraceSwitch _defaultTraceSwitch =
303+
new TraceSwitch("DataConnection", "DataConnection trace switch", TraceLevel.Info.ToString());
304+
305+
static void EnableTracing(DataConnection dc, ILogger logger)
306+
{
307+
dc.OnTraceConnection = t => Implementation.LogConnectionTrace(t, logger);
308+
dc.TraceSwitchConnection = _defaultTraceSwitch;
309+
}
310+
299311
public static ILogger CreateLogger(IDbContextOptions options)
300312
{
301313
return Implementation.CreateLogger(options);
@@ -356,7 +368,9 @@ public static IDataContext CreateLinqToDbContext(this DbContext context,
356368
dc.AddMappingSchema(mappingSchema);
357369

358370
if (logger != null)
359-
dc.OnTraceConnection = t => Implementation.LogConnectionTrace(t, logger);
371+
{
372+
EnableTracing(dc, logger);
373+
}
360374

361375
return dc;
362376
}
@@ -377,8 +391,11 @@ public static DataConnection CreateLinq2DbConnectionDetached([JetBrains.Annotati
377391

378392
var dc = new LinqToDBForEFToolsDataConnection(context, dataProvider, connectionInfo.ConnectionString, context.Model, TransformExpression);
379393
var logger = CreateLogger(info.Options);
394+
380395
if (logger != null)
381-
dc.OnTraceConnection = t => Implementation.LogConnectionTrace(t, logger);
396+
{
397+
EnableTracing(dc, logger);
398+
}
382399

383400
var dependencies = context.GetService<RelationalSqlTranslatingExpressionVisitorDependencies>();
384401
var mappingSource = context.GetService<IRelationalTypeMappingSource>();
@@ -472,7 +489,9 @@ public static DataConnection CreateLinqToDbConnection(this DbContextOptions opti
472489

473490
var logger = CreateLogger(info.Options);
474491
if (logger != null)
475-
dc.OnTraceConnection = t => Implementation.LogConnectionTrace(t, logger);
492+
{
493+
EnableTracing(dc, logger);
494+
}
476495

477496
if (model != null)
478497
{

Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFToolsImplDefault.cs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -502,13 +502,9 @@ public virtual IDbContextOptions GetContextOptions(DbContext context)
502502

503503
static readonly MethodInfo GetTableMethodInfo = MemberHelper.MethodOfGeneric<IDataContext>(dc => dc.GetTable<object>());
504504

505-
static readonly MethodInfo EnumerableWhereMethodInfo = MemberHelper.MethodOfGeneric<IEnumerable<object>>(q => q.Where(p => true));
506-
507505
static readonly MethodInfo FromSqlOnQueryableMethodInfo =
508506
typeof(RelationalQueryableExtensions).GetMethods(BindingFlags.Static|BindingFlags.NonPublic).Single(x => x.Name == "FromSqlOnQueryable").GetGenericMethodDefinition();
509507

510-
static readonly MethodInfo EnumerableToListMethodInfo = MemberHelper.MethodOfGeneric<IEnumerable<object>>(q => q.ToList());
511-
512508
static readonly MethodInfo IgnoreQueryFiltersMethodInfo = MemberHelper.MethodOfGeneric<IQueryable<object>>(q => q.IgnoreQueryFilters());
513509

514510
static readonly MethodInfo IncludeMethodInfo = MemberHelper.MethodOfGeneric<IQueryable<object>>(q => q.Include(o => o.ToString()));
@@ -714,17 +710,29 @@ Expression LocalTransform(Expression e)
714710
{
715711
case ExpressionType.Constant:
716712
{
717-
if (typeof(EntityQueryable<>).IsSameOrParentOf(e.Type))
713+
if (typeof(EntityQueryable<>).IsSameOrParentOf(e.Type) || typeof(DbSet<>).IsSameOrParentOf(e.Type))
718714
{
719715
var entityType = e.Type.GenericTypeArguments[0];
720716
var newExpr = Expression.Call(null, Methods.LinqToDB.GetTable.MakeGenericMethod(entityType), Expression.Constant(dc));
721-
722717
return newExpr;
723718
}
724719

725720
break;
726721
}
727722

723+
case ExpressionType.MemberAccess:
724+
{
725+
if (typeof(DbSet<>).IsSameOrParentOf(e.Type))
726+
{
727+
var ma = (MemberExpression)e;
728+
var query = (IQueryable)EvaluateExpression(ma);
729+
730+
return LocalTransform(query.Expression);
731+
}
732+
733+
break;
734+
}
735+
728736
case ExpressionType.Call:
729737
{
730738
var methodCall = (MethodCallExpression) e;
@@ -998,7 +1006,7 @@ private Expression AddFilter(Dictionary<Type, Expression> cachedFilters, Type en
9981006
}
9991007
else if (typeof(IEnumerable<>).MakeGenericType(entityType).IsSameOrParentOf(expression.Type))
10001008
{
1001-
expression = Expression.Call(EnumerableWhereMethodInfo.MakeGenericMethod(entityType), expression,
1009+
expression = Expression.Call(Methods.Enumerable.Where.MakeGenericMethod(entityType), expression,
10021010
filterExpression);
10031011
}
10041012

@@ -1068,7 +1076,7 @@ private Expression ApplyQueryFiltersTODO(Expression expression, HashSet<Expressi
10681076
if (typeof(ICollection<>).IsSameOrParentOf(e.Type))
10691077
{
10701078
filtered = Expression.Call(
1071-
EnumerableToListMethodInfo.MakeGenericMethod(navigationType), filtered);
1079+
Methods.Enumerable.ToList.MakeGenericMethod(navigationType), filtered);
10721080
}
10731081
else if (e.Type.IsArray)
10741082
{

Source/LinqToDB.EntityFrameworkCore/linq2db.EntityFrameworkCore.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
</PropertyGroup>
1010

1111
<ItemGroup>
12-
<PackageReference Include="linq2db" Version="3.1.5" />
13-
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.3" />
12+
<PackageReference Include="linq2db" Version="3.1.6" />
13+
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.10" />
1414
</ItemGroup>
1515

1616
</Project>

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFrameworks>netcoreapp3.0</TargetFrameworks>
4+
<TargetFrameworks>netcoreapp3.1</TargetFrameworks>
55
</PropertyGroup>
66

77
<ItemGroup>
@@ -11,11 +11,12 @@
1111
</ItemGroup>
1212

1313
<ItemGroup>
14-
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="3.1.3" />
15-
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.3" />
16-
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.3" />
17-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
18-
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1">
14+
<PackageReference Include="linq2db.Tools" Version="3.1.6" />
15+
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="3.1.10" />
16+
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.10" />
17+
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.10" />
18+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.0" />
19+
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0">
1920
<PrivateAssets>all</PrivateAssets>
2021
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2122
</PackageReference>

Tests/LinqToDB.EntityFrameworkCore.BaseTests/TestsBase.cs

Lines changed: 79 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,57 +3,103 @@
33
using System.Diagnostics;
44
using System.Linq;
55
using System.Text;
6+
using LinqToDB.Reflection;
7+
using LinqToDB.Tools;
8+
using LinqToDB.Tools.Comparers;
69
using NUnit.Framework;
710

811
namespace LinqToDB.EntityFrameworkCore.BaseTests
912
{
1013
public class TestsBase
1114
{
12-
protected void AreEqual<T>(IEnumerable<T> expected, IEnumerable<T> result)
15+
protected void AreEqual<T>(IEnumerable<T> expected, IEnumerable<T> result, bool allowEmpty = false)
1316
{
14-
AreEqual(t => t, expected, result, EqualityComparer<T>.Default);
17+
AreEqual(t => t, expected, result, EqualityComparer<T>.Default, allowEmpty);
18+
}
19+
20+
protected void AreEqual<T>(IEnumerable<T> expected, IEnumerable<T> result, Func<IEnumerable<T>, IEnumerable<T>> sort)
21+
{
22+
AreEqual(t => t, expected, result, EqualityComparer<T>.Default, sort);
23+
}
24+
25+
protected void AreEqualWithComparer<T>(IEnumerable<T> expected, IEnumerable<T> result)
26+
{
27+
AreEqual(t => t, expected, result, ComparerBuilder.GetEqualityComparer<T>());
28+
}
29+
30+
protected void AreEqualWithComparer<T>(IEnumerable<T> expected, IEnumerable<T> result, Func<MemberAccessor, bool> memberPredicate)
31+
{
32+
AreEqual(t => t, expected, result, ComparerBuilder.GetEqualityComparer<T>(memberPredicate));
1533
}
1634

1735
protected void AreEqual<T>(IEnumerable<T> expected, IEnumerable<T> result, IEqualityComparer<T> comparer)
1836
{
1937
AreEqual(t => t, expected, result, comparer);
2038
}
2139

22-
protected void AreEqual<T>(Func<T,T> fixSelector, IEnumerable<T> expected, IEnumerable<T> result)
40+
protected void AreEqual<T>(IEnumerable<T> expected, IEnumerable<T> result, IEqualityComparer<T> comparer, Func<IEnumerable<T>, IEnumerable<T>> sort)
41+
{
42+
AreEqual(t => t, expected, result, comparer, sort);
43+
}
44+
45+
protected void AreEqual<T>(Func<T, T> fixSelector, IEnumerable<T> expected, IEnumerable<T> result)
2346
{
2447
AreEqual(fixSelector, expected, result, EqualityComparer<T>.Default);
2548
}
2649

27-
protected void AreEqual<T>(Func<T,T> fixSelector, IEnumerable<T> expected, IEnumerable<T> result, IEqualityComparer<T> comparer)
50+
protected void AreEqual<T>(Func<T, T> fixSelector, IEnumerable<T> expected, IEnumerable<T> result, IEqualityComparer<T> comparer, bool allowEmpty = false)
2851
{
29-
var resultList = result. Select(fixSelector).ToList();
52+
AreEqual<T>(fixSelector, expected, result, comparer, null, allowEmpty);
53+
}
54+
55+
protected void AreEqual<T>(
56+
Func<T, T> fixSelector,
57+
IEnumerable<T> expected,
58+
IEnumerable<T> result,
59+
IEqualityComparer<T> comparer,
60+
Func<IEnumerable<T>, IEnumerable<T>>? sort,
61+
bool allowEmpty = false)
62+
{
63+
var resultList = result.Select(fixSelector).ToList();
3064
var expectedList = expected.Select(fixSelector).ToList();
3165

32-
Assert.AreNotEqual(0, expectedList.Count, "Expected list cannot be empty.");
66+
if (sort != null)
67+
{
68+
resultList = sort(resultList).ToList();
69+
expectedList = sort(expectedList).ToList();
70+
}
71+
72+
if (!allowEmpty)
73+
Assert.AreNotEqual(0, expectedList.Count, "Expected list cannot be empty.");
3374
Assert.AreEqual(expectedList.Count, resultList.Count, "Expected and result lists are different. Length: ");
3475

35-
var exceptExpectedList = resultList. Except(expectedList, comparer).ToList();
36-
var exceptResultList = expectedList.Except(resultList, comparer).ToList();
76+
var exceptExpectedList = resultList.Except(expectedList, comparer).ToList();
77+
var exceptResultList = expectedList.Except(resultList, comparer).ToList();
3778

3879
var exceptExpected = exceptExpectedList.Count;
39-
var exceptResult = exceptResultList. Count;
40-
var message = new StringBuilder();
80+
var exceptResult = exceptResultList.Count;
81+
var message = new StringBuilder();
4182

4283
if (exceptResult != 0 || exceptExpected != 0)
84+
{
85+
Debug.WriteLine(resultList.ToDiagnosticString());
86+
Debug.WriteLine(expectedList.ToDiagnosticString());
87+
4388
for (var i = 0; i < resultList.Count; i++)
4489
{
45-
Debug. WriteLine ("{0} {1} --- {2}", comparer.Equals(expectedList[i], resultList[i]) ? " " : "-", expectedList[i], resultList[i]);
90+
Debug.WriteLine("{0} {1} --- {2}", comparer.Equals(expectedList[i], resultList[i]) ? " " : "-", expectedList[i], resultList[i]);
4691
message.AppendFormat("{0} {1} --- {2}", comparer.Equals(expectedList[i], resultList[i]) ? " " : "-", expectedList[i], resultList[i]);
47-
message.AppendLine ();
92+
message.AppendLine();
4893
}
94+
}
4995

5096
Assert.AreEqual(0, exceptExpected, $"Expected Was{Environment.NewLine}{message}");
51-
Assert.AreEqual(0, exceptResult, $"Expect Result{Environment.NewLine}{message}");
97+
Assert.AreEqual(0, exceptResult, $"Expect Result{Environment.NewLine}{message}");
5298
}
5399

54100
protected void AreEqual<T>(IEnumerable<IEnumerable<T>> expected, IEnumerable<IEnumerable<T>> result)
55101
{
56-
var resultList = result. ToList();
102+
var resultList = result.ToList();
57103
var expectedList = expected.ToList();
58104

59105
Assert.AreNotEqual(0, expectedList.Count);
@@ -62,12 +108,29 @@ protected void AreEqual<T>(IEnumerable<IEnumerable<T>> expected, IEnumerable<IEn
62108
for (var i = 0; i < resultList.Count; i++)
63109
{
64110
var elist = expectedList[i].ToList();
65-
var rlist = resultList [i].ToList();
111+
var rlist = resultList[i].ToList();
66112

67113
if (elist.Count > 0 || rlist.Count > 0)
68114
AreEqual(elist, rlist);
69115
}
70116
}
71-
117+
118+
protected void AreSame<T>(IEnumerable<T> expected, IEnumerable<T> result)
119+
{
120+
var resultList = result.ToList();
121+
var expectedList = expected.ToList();
122+
123+
Assert.AreNotEqual(0, expectedList.Count);
124+
Assert.AreEqual(expectedList.Count, resultList.Count);
125+
126+
var b = expectedList.SequenceEqual(resultList);
127+
128+
if (!b)
129+
for (var i = 0; i < resultList.Count; i++)
130+
Debug.WriteLine("{0} {1} --- {2}", Equals(expectedList[i], resultList[i]) ? " " : "-", expectedList[i], resultList[i]);
131+
132+
Assert.IsTrue(b);
133+
}
134+
72135
}
73136
}

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFrameworks>netcoreapp3.0</TargetFrameworks>
4+
<TargetFrameworks>netcoreapp3.1</TargetFrameworks>
55
</PropertyGroup>
66

77
<ItemGroup>
@@ -11,13 +11,13 @@
1111
</ItemGroup>
1212

1313
<ItemGroup>
14-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
15-
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1">
14+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.0" />
15+
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0">
1616
<PrivateAssets>all</PrivateAssets>
1717
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1818
</PackageReference>
1919
<PackageReference Include="NUnit" Version="3.12.0" />
20-
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.1.1" />
20+
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.2.4" />
2121
</ItemGroup>
2222

2323
<ItemGroup>

0 commit comments

Comments
 (0)