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

Commit 792f787

Browse files
committed
Merge branch 'master' into release
# Conflicts: # appveyor.yml
2 parents a35421c + 762e2b3 commit 792f787

File tree

9 files changed

+645
-42
lines changed

9 files changed

+645
-42
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,10 @@ using (var dc = options.CreateLinqToDbConnection())
7878
}
7979
```
8080

81-
You can use all `LINQ To DB` extension functions in your EF linq queries. Just ensure you have called `ToLinqToDB()` function before materializing objects.
81+
You can use all `LINQ To DB` extension functions in your EF linq queries. Just ensure you have called `ToLinqToDB()` function before materializing objects for synchronous methods.
82+
83+
Since EF Core have defined it's own asynchronous methods, we have to duplicate them to resolve naming collisions.
84+
Async methods have the same name but with `LinqToDB` suffix. E.g. `ToListAsyncLinqToDB()`, `SumAsyncLinqToDB()`, ect. The same methods are added whe you need `EF Core` query processing but there is collision with `LINQ To DB` and they have extensions with `EF` suffix - `ToListAsyncEF()`, `SumAsyncEF()`, ect.
8285

8386
```cs
8487
using (var ctx = CreateAdventureWorksContext())

Source/LinqToDB.EntityFrameworkCore/Internal/LinqToDBForEFQueryProvider.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ namespace LinqToDB.EntityFrameworkCore.Internal
2121
/// It may change or be removed without further notice.
2222
/// </summary>
2323
/// <typeparam name="T"></typeparam>
24-
public class LinqToDBForEFQueryProvider<T> : IAsyncQueryProvider, IQueryable<T>, System.Collections.Generic.IAsyncEnumerable<T>
24+
public class LinqToDBForEFQueryProvider<T> : IAsyncQueryProvider, IQueryProviderAsync, IQueryable<T>, System.Collections.Generic.IAsyncEnumerable<T>
2525
{
2626
public LinqToDBForEFQueryProvider([NotNull] IDataContext dataContext, [NotNull] Expression expression)
2727
{
@@ -59,6 +59,11 @@ public System.Collections.Generic.IAsyncEnumerable<TResult> ExecuteAsync<TResult
5959
return new AsyncEnumerableAdaper<TResult>(QueryProvider.ExecuteAsync<TResult>(expression));
6060
}
6161

62+
IAsyncEnumerable<TResult> IQueryProviderAsync.ExecuteAsync<TResult>(Expression expression)
63+
{
64+
return QueryProvider.ExecuteAsync<TResult>(expression);
65+
}
66+
6267
public Task<TResult> ExecuteAsync<TResult>(Expression expression, CancellationToken cancellationToken)
6368
{
6469
return QueryProvider.ExecuteAsync<TResult>(expression, cancellationToken);

Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFExtensions.Async.EF.cs

Lines changed: 517 additions & 0 deletions
Large diffs are not rendered by default.

Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFExtensions.Async.cs

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -286,54 +286,54 @@ public static Task<TResult> MaxAsyncLinqToDB<TSource,TResult>(
286286
CancellationToken token = default)
287287
=> AsyncExtensions.MaxAsync(source.ToLinqToDB(), selector, token);
288288

289-
#region SumAsync
289+
#region SumAsyncLinqToDB
290290

291-
public static Task<int> SumAsync(
291+
public static Task<int> SumAsyncLinqToDB(
292292
this IQueryable<int> source,
293293
CancellationToken token = default)
294294
=> AsyncExtensions.SumAsync(source.ToLinqToDB(), token);
295295

296-
public static Task<int?> SumAsync(
296+
public static Task<int?> SumAsyncLinqToDB(
297297
this IQueryable<int?> source,
298298
CancellationToken token = default)
299299
=> AsyncExtensions.SumAsync(source.ToLinqToDB(), token);
300300

301-
public static Task<long> SumAsync(
301+
public static Task<long> SumAsyncLinqToDB(
302302
this IQueryable<long> source,
303303
CancellationToken token = default)
304304
=> AsyncExtensions.SumAsync(source.ToLinqToDB(), token);
305305

306-
public static Task<long?> SumAsync(
306+
public static Task<long?> SumAsyncLinqToDB(
307307
this IQueryable<long?> source,
308308
CancellationToken token = default)
309309
=> AsyncExtensions.SumAsync(source.ToLinqToDB(), token);
310310

311-
public static Task<float> SumAsync(
311+
public static Task<float> SumAsyncLinqToDB(
312312
this IQueryable<float> source,
313313
CancellationToken token = default)
314314
=> AsyncExtensions.SumAsync(source.ToLinqToDB(), token);
315315

316-
public static Task<float?> SumAsync(
316+
public static Task<float?> SumAsyncLinqToDB(
317317
this IQueryable<float?> source,
318318
CancellationToken token = default)
319319
=> AsyncExtensions.SumAsync(source.ToLinqToDB(), token);
320320

321-
public static Task<double> SumAsync(
321+
public static Task<double> SumAsyncLinqToDB(
322322
this IQueryable<double> source,
323323
CancellationToken token = default)
324324
=> AsyncExtensions.SumAsync(source.ToLinqToDB(), token);
325325

326-
public static Task<double?> SumAsync(
326+
public static Task<double?> SumAsyncLinqToDB(
327327
this IQueryable<double?> source,
328328
CancellationToken token = default)
329329
=> AsyncExtensions.SumAsync(source.ToLinqToDB(), token);
330330

331-
public static Task<decimal> SumAsync(
331+
public static Task<decimal> SumAsyncLinqToDB(
332332
this IQueryable<decimal> source,
333333
CancellationToken token = default)
334334
=> AsyncExtensions.SumAsync(source.ToLinqToDB(), token);
335335

336-
public static Task<decimal?> SumAsync(
336+
public static Task<decimal?> SumAsyncLinqToDB(
337337
this IQueryable<decimal?> source,
338338
CancellationToken token = default)
339339
=> AsyncExtensions.SumAsync(source.ToLinqToDB(), token);
@@ -398,56 +398,56 @@ public static Task<decimal> SumAsyncLinqToDB<TSource>(
398398
CancellationToken token = default)
399399
=> AsyncExtensions.SumAsync(source.ToLinqToDB(), selector, token);
400400

401-
#endregion SumAsync
401+
#endregion SumAsyncLinqToDB
402402

403-
#region AverageAsync
403+
#region AverageAsyncLinqToDB
404404

405-
public static Task<double> AverageAsync(
405+
public static Task<double> AverageAsyncLinqToDB(
406406
this IQueryable<int> source,
407407
CancellationToken token = default)
408408
=> AsyncExtensions.AverageAsync(source.ToLinqToDB(), token);
409409

410-
public static Task<double?> AverageAsync(
410+
public static Task<double?> AverageAsyncLinqToDB(
411411
this IQueryable<int?> source,
412412
CancellationToken token = default)
413413
=> AsyncExtensions.AverageAsync(source.ToLinqToDB(), token);
414414

415-
public static Task<double> AverageAsync(
415+
public static Task<double> AverageAsyncLinqToDB(
416416
this IQueryable<long> source,
417417
CancellationToken token = default)
418418
=> AsyncExtensions.AverageAsync(source.ToLinqToDB(), token);
419419

420-
public static Task<double?> AverageAsync(
420+
public static Task<double?> AverageAsyncLinqToDB(
421421
this IQueryable<long?> source,
422422
CancellationToken token = default)
423423
=> AsyncExtensions.AverageAsync(source.ToLinqToDB(), token);
424424

425-
public static Task<float> AverageAsync(
425+
public static Task<float> AverageAsyncLinqToDB(
426426
this IQueryable<float> source,
427427
CancellationToken token = default)
428428
=> AsyncExtensions.AverageAsync(source.ToLinqToDB(), token);
429429

430-
public static Task<float?> AverageAsync(
430+
public static Task<float?> AverageAsyncLinqToDB(
431431
this IQueryable<float?> source,
432432
CancellationToken token = default)
433433
=> AsyncExtensions.AverageAsync(source.ToLinqToDB(), token);
434434

435-
public static Task<double> AverageAsync(
435+
public static Task<double> AverageAsyncLinqToDB(
436436
this IQueryable<double> source,
437437
CancellationToken token = default)
438438
=> AsyncExtensions.AverageAsync(source.ToLinqToDB(), token);
439439

440-
public static Task<double?> AverageAsync(
440+
public static Task<double?> AverageAsyncLinqToDB(
441441
this IQueryable<double?> source,
442442
CancellationToken token = default)
443443
=> AsyncExtensions.AverageAsync(source.ToLinqToDB(), token);
444444

445-
public static Task<decimal> AverageAsync(
445+
public static Task<decimal> AverageAsyncLinqToDB(
446446
this IQueryable<decimal> source,
447447
CancellationToken token = default)
448448
=> AsyncExtensions.AverageAsync(source.ToLinqToDB(), token);
449449

450-
public static Task<decimal?> AverageAsync(
450+
public static Task<decimal?> AverageAsyncLinqToDB(
451451
this IQueryable<decimal?> source,
452452
CancellationToken token = default)
453453
=> AsyncExtensions.AverageAsync(source.ToLinqToDB(), token);
@@ -512,6 +512,6 @@ public static Task<decimal> AverageAsyncLinqToDB<TSource>(
512512
CancellationToken token = default)
513513
=> AsyncExtensions.AverageAsync(source.ToLinqToDB(), selector, token);
514514

515-
#endregion AverageAsync
515+
#endregion AverageAsyncLinqToDB
516516
}
517517
}

Source/LinqToDB.EntityFrameworkCore/linq2db.EntityFrameworkCore.csproj

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

1111
<ItemGroup>
12-
<PackageReference Include="linq2db" Version="2.2.0" />
13-
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="2.1.1" />
14-
<PackageReference Include="System.Interactive.Async" Version="3.1.1" />
12+
<PackageReference Include="linq2db" Version="2.5.4" />
13+
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="2.2.0" />
1514
</ItemGroup>
1615

1716
</Project>
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using LinqToDB;
2+
using LinqToDB.Data;
3+
using LinqToDB.EntityFrameworkCore;
4+
using LinqToDB.EntityFrameworkCore.Tests;
5+
using Microsoft.EntityFrameworkCore;
6+
using Microsoft.EntityFrameworkCore.SqlAzure.Model;
7+
using NUnit.Framework;
8+
9+
namespace SomeNamespace
10+
{
11+
[TestFixture]
12+
public class ConflictTest
13+
{
14+
private readonly DbContextOptions _options;
15+
private DbContextOptions<AdventureWorksContext> _inmemoryOptions;
16+
17+
static ConflictTest()
18+
{
19+
LinqToDBForEFTools.Initialize();
20+
DataConnection.TurnTraceSwitchOn();
21+
}
22+
23+
public ConflictTest()
24+
{
25+
var optionsBuilder = new DbContextOptionsBuilder<AdventureWorksContext>();
26+
//new SqlServerDbContextOptionsBuilder(optionsBuilder);
27+
28+
optionsBuilder.UseSqlServer("Server=.;Database=AdventureWorks;Integrated Security=SSPI");
29+
optionsBuilder.UseLoggerFactory(TestUtils.LoggerFactory);
30+
31+
_options = optionsBuilder.Options;
32+
33+
optionsBuilder = new DbContextOptionsBuilder<AdventureWorksContext>();
34+
//new SqlServerDbContextOptionsBuilder(optionsBuilder);
35+
36+
optionsBuilder.UseInMemoryDatabase("sample");
37+
optionsBuilder.UseLoggerFactory(TestUtils.LoggerFactory);
38+
39+
_inmemoryOptions = optionsBuilder.Options;
40+
}
41+
42+
private AdventureWorksContext CreateAdventureWorksContext()
43+
{
44+
var ctx = new AdventureWorksContext(_options);
45+
ctx.Database.EnsureCreated();
46+
return ctx;
47+
}
48+
49+
[Test]
50+
public void TestToList()
51+
{
52+
using (var ctx = CreateAdventureWorksContext())
53+
using (var db = ctx.CreateLinqToDbConnection())
54+
{
55+
var items = ctx.Addresses.AsNoTracking().ToListAsyncEF();
56+
}
57+
}
58+
59+
}
60+
}

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66

77
<ItemGroup>
88
<PackageReference Include="JetBrains.DotMemoryUnit" Version="3.0.20171219.105559" />
9-
<PackageReference Include="linq2db.MySql" Version="2.0.0-beta5" />
10-
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="2.1.1" />
11-
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.1.0-rc1-final" />
12-
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.1.0-rc1-final" />
13-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
14-
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.1.0-preview2" />
15-
<PackageReference Include="NUnit" Version="3.10.1" />
16-
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.0.1" />
9+
<PackageReference Include="linq2db" Version="2.5.4" />
10+
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="2.2.0" />
11+
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.2.0" />
12+
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.2.0" />
13+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
14+
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.1.2" />
15+
<PackageReference Include="NUnit" Version="3.11.0" />
16+
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.1.4" />
1717
</ItemGroup>
1818

1919
<ItemGroup>

Tests/LinqToDB.EntityFrameworkCore.Tests/ToolsTests.cs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Linq;
44
using System.Threading.Tasks;
55
using LinqToDB.Data;
6+
using LinqToDB.EntityFrameworkCore;
67
using LinqToDB.Expressions;
78
using LinqToDB.Mapping;
89
using NUnit.Framework;
@@ -12,6 +13,9 @@
1213
using Microsoft.Extensions.Logging;
1314
using Microsoft.Extensions.Logging.Console;
1415

16+
using LinqToDB;
17+
using LinqToDB.EntityFrameworkCore.Tests;
18+
1519
namespace LinqToDB.EntityFrameworkCore.Tests
1620
{
1721
[TestFixture]
@@ -274,7 +278,7 @@ orderby p.ProductID
274278
}
275279

276280
[Test]
277-
public void TestTransaction()
281+
public async Task TestTransaction()
278282
{
279283
using (var ctx = CreateAdventureWorksContext())
280284
{
@@ -297,8 +301,8 @@ public void TestTransaction()
297301
.Delete();
298302

299303

300-
var test1 = ctx.Products.Where(p => p.Name.StartsWith("U")).MaxAsync(p => p.StandardCost).Result;
301-
var test2 = ctx.Products.Where(p => p.Name.StartsWith("U")).MaxAsyncLinqToDB(p => p.StandardCost).Result;
304+
var test1 = await ctx.Products.Where(p => p.Name.StartsWith("U")).MaxAsync(p => p.StandardCost);
305+
var test2 = await ctx.Products.Where(p => p.Name.StartsWith("U")).MaxAsyncLinqToDB(p => p.StandardCost);
302306

303307
Assert.AreEqual(test1, test2);
304308

@@ -557,6 +561,21 @@ public async Task TestContinuousQueries()
557561

558562
}
559563

564+
[Test]
565+
public async Task TestSetUpdate()
566+
{
567+
using (var ctx = CreateAdventureWorksContext())
568+
{
569+
var customer = await ctx.Customers.FirstOrDefaultAsync();
570+
571+
var updatable = ctx.Customers.Where(c => c.CustomerID == customer.CustomerID)
572+
.Set(c => c.CompanyName, customer.CompanyName);
573+
574+
var affected = updatable
575+
.UpdateAsync();
576+
}
577+
}
578+
560579

561580
}
562581
}

appveyor.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ branches:
1010
- /dev.*/
1111

1212
environment:
13-
assemblyVersion: 1.2.1
14-
packageVersion: 1.2.1
13+
assemblyVersion: 1.3.0
14+
packageVersion: 1.3.0
1515
access_token:
1616
secure: IlfmHXRdUK6v8dX/WqieXQ==
1717

0 commit comments

Comments
 (0)