mirror of
https://github.com/zoriya/EntityFrameworkCore.Projectables.git
synced 2026-05-31 21:48:12 +00:00
Fixed concurrency bug
This commit is contained in:
@@ -92,11 +92,12 @@ namespace BasicSample
|
|||||||
dbConnection.Open();
|
dbConnection.Open();
|
||||||
|
|
||||||
using var serviceProvider = new ServiceCollection()
|
using var serviceProvider = new ServiceCollection()
|
||||||
.AddDbContext<ApplicationDbContext>(options => {
|
.AddEntityFrameworkSqlServer()
|
||||||
|
.AddDbContext<ApplicationDbContext>((provider, options) => {
|
||||||
options
|
options
|
||||||
.UseSqlite(dbConnection)
|
.UseSqlite(dbConnection)
|
||||||
.UseProjectables()
|
.UseProjectables()
|
||||||
.UseLoggerFactory(LoggerFactory.Create(builder => builder.AddConsole()));
|
.UseInternalServiceProvider(provider);
|
||||||
})
|
})
|
||||||
.BuildServiceProvider();
|
.BuildServiceProvider();
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,6 @@ namespace EntityFrameworkCore.Projectables.Extensions
|
|||||||
{
|
{
|
||||||
public static class ExpressionExtensions
|
public static class ExpressionExtensions
|
||||||
{
|
{
|
||||||
static ProjectableExpressionReplacer _projectableExpressionReplacer = new ProjectableExpressionReplacer(new ProjectionExpressionResolver());
|
|
||||||
|
|
||||||
[Obsolete("Use ExpandProjectables instead")]
|
[Obsolete("Use ExpandProjectables instead")]
|
||||||
public static Expression ExpandQuaryables(this Expression expression)
|
public static Expression ExpandQuaryables(this Expression expression)
|
||||||
=> ExpandProjectables(expression);
|
=> ExpandProjectables(expression);
|
||||||
@@ -20,6 +18,6 @@ namespace EntityFrameworkCore.Projectables.Extensions
|
|||||||
/// Replaces all calls to properties and methods that are marked with the <C>Projectable</C> attribute with their respective expression tree
|
/// Replaces all calls to properties and methods that are marked with the <C>Projectable</C> attribute with their respective expression tree
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static Expression ExpandProjectables(this Expression expression)
|
public static Expression ExpandProjectables(this Expression expression)
|
||||||
=> _projectableExpressionReplacer.Visit(expression);
|
=> new ProjectableExpressionReplacer(new ProjectionExpressionResolver()).Visit(expression);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Transactions;
|
|
||||||
using EntityFrameworkCore.Projectables.Services;
|
|
||||||
using Microsoft.EntityFrameworkCore.Query;
|
|
||||||
using Microsoft.EntityFrameworkCore.Query.Internal;
|
|
||||||
|
|
||||||
namespace EntityFrameworkCore.Projectables.Infrastructure.Internal
|
|
||||||
{
|
|
||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "EF1001:Internal EF Core API usage.", Justification = "Needed")]
|
|
||||||
public sealed class CustomQueryProvider : IQueryCompiler
|
|
||||||
{
|
|
||||||
readonly IQueryCompiler _decoratedQueryCompiler;
|
|
||||||
readonly ProjectableExpressionReplacer _projectableExpressionReplacer;
|
|
||||||
|
|
||||||
public CustomQueryProvider(IQueryCompiler decoratedQueryCompiler)
|
|
||||||
{
|
|
||||||
_decoratedQueryCompiler = decoratedQueryCompiler;
|
|
||||||
_projectableExpressionReplacer = new ProjectableExpressionReplacer(new ProjectionExpressionResolver());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Func<QueryContext, TResult> CreateCompiledAsyncQuery<TResult>(Expression query)
|
|
||||||
=> _decoratedQueryCompiler.CreateCompiledAsyncQuery<TResult>(Expand(query));
|
|
||||||
public Func<QueryContext, TResult> CreateCompiledQuery<TResult>(Expression query)
|
|
||||||
=> _decoratedQueryCompiler.CreateCompiledQuery<TResult>(Expand(query));
|
|
||||||
public TResult Execute<TResult>(Expression query)
|
|
||||||
=> _decoratedQueryCompiler.Execute<TResult>(Expand(query));
|
|
||||||
public TResult ExecuteAsync<TResult>(Expression query, CancellationToken cancellationToken)
|
|
||||||
=> _decoratedQueryCompiler.ExecuteAsync<TResult>(Expand(query), cancellationToken);
|
|
||||||
|
|
||||||
Expression Expand(Expression expression)
|
|
||||||
=> _projectableExpressionReplacer.Visit(expression);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
using System.Linq.Expressions;
|
||||||
|
using EntityFrameworkCore.Projectables.Extensions;
|
||||||
|
using Microsoft.EntityFrameworkCore.Query;
|
||||||
|
|
||||||
|
namespace EntityFrameworkCore.Projectables.Infrastructure.Internal
|
||||||
|
{
|
||||||
|
public class CustomQueryTranslationPreprocessor : QueryTranslationPreprocessor
|
||||||
|
{
|
||||||
|
readonly QueryTranslationPreprocessor _decoratedPreprocessor;
|
||||||
|
|
||||||
|
public CustomQueryTranslationPreprocessor(QueryTranslationPreprocessor decoratedPreprocessor, QueryTranslationPreprocessorDependencies dependencies, QueryCompilationContext queryCompilationContext) : base(dependencies, queryCompilationContext)
|
||||||
|
{
|
||||||
|
_decoratedPreprocessor = decoratedPreprocessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Expression Process(Expression query)
|
||||||
|
=> _decoratedPreprocessor.Process(query.ExpandProjectables());
|
||||||
|
}
|
||||||
|
}
|
||||||
-15
@@ -1,10 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using EntityFrameworkCore.Projectables.Extensions;
|
|
||||||
using EntityFrameworkCore.Projectables.Services;
|
using EntityFrameworkCore.Projectables.Services;
|
||||||
using Microsoft.EntityFrameworkCore.Query;
|
using Microsoft.EntityFrameworkCore.Query;
|
||||||
|
|
||||||
@@ -24,17 +22,4 @@ namespace EntityFrameworkCore.Projectables.Infrastructure.Internal
|
|||||||
public QueryTranslationPreprocessor Create(QueryCompilationContext queryCompilationContext)
|
public QueryTranslationPreprocessor Create(QueryCompilationContext queryCompilationContext)
|
||||||
=> new CustomQueryTranslationPreprocessor(_decoratedFactory.Create(queryCompilationContext), _queryTranslationPreprocessorDependencies, queryCompilationContext);
|
=> new CustomQueryTranslationPreprocessor(_decoratedFactory.Create(queryCompilationContext), _queryTranslationPreprocessorDependencies, queryCompilationContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CustomQueryTranslationPreprocessor : QueryTranslationPreprocessor
|
|
||||||
{
|
|
||||||
readonly QueryTranslationPreprocessor _decoratedPreprocessor;
|
|
||||||
|
|
||||||
public CustomQueryTranslationPreprocessor(QueryTranslationPreprocessor decoratedPreprocessor, QueryTranslationPreprocessorDependencies dependencies, QueryCompilationContext queryCompilationContext) : base(dependencies, queryCompilationContext)
|
|
||||||
{
|
|
||||||
_decoratedPreprocessor = decoratedPreprocessor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Expression Process(Expression query)
|
|
||||||
=> _decoratedPreprocessor.Process(query.ExpandProjectables());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+1
-1
@@ -57,7 +57,7 @@ namespace EntityFrameworkCore.Projectables.Infrastructure.Internal
|
|||||||
throw new InvalidOperationException("No QueryProvider is configured yet. Please make sure to configure a database provider first"); ;
|
throw new InvalidOperationException("No QueryProvider is configured yet. Please make sure to configure a database provider first"); ;
|
||||||
}
|
}
|
||||||
|
|
||||||
var decoratorObjectFactory = ActivatorUtilities.CreateFactory(typeof(CustomQueryProvider), new[] { targetDescriptor.ServiceType });
|
var decoratorObjectFactory = ActivatorUtilities.CreateFactory(typeof(CustomQueryCompiler), new[] { targetDescriptor.ServiceType });
|
||||||
|
|
||||||
services.Replace(ServiceDescriptor.Describe(
|
services.Replace(ServiceDescriptor.Describe(
|
||||||
targetDescriptor.ServiceType,
|
targetDescriptor.ServiceType,
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace EntityFrameworkCore.Projectables.FunctionalTests.Helpers
|
|||||||
|
|
||||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||||
{
|
{
|
||||||
optionsBuilder.UseSqlServer("Server=(localdb)\v11.0;Integrated Security=true"); // Fake connection string as we're actually never connecting
|
optionsBuilder.UseSqlServer("Server=(localdb)\\v11.0;Integrated Security=true"); // Fake connection string as we're actually never connecting
|
||||||
optionsBuilder.UseProjectables(options => {
|
optionsBuilder.UseProjectables(options => {
|
||||||
options.CompatibilityMode(_compatibilityMode); // Needed by our ComplexModelTests
|
options.CompatibilityMode(_compatibilityMode); // Needed by our ComplexModelTests
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user