mirror of
https://github.com/zoriya/EntityFrameworkCore.Projectables.git
synced 2025-12-06 05:56:10 +00:00
Fixed concurrency bug
This commit is contained in:
@@ -92,11 +92,12 @@ namespace BasicSample
|
||||
dbConnection.Open();
|
||||
|
||||
using var serviceProvider = new ServiceCollection()
|
||||
.AddDbContext<ApplicationDbContext>(options => {
|
||||
.AddEntityFrameworkSqlServer()
|
||||
.AddDbContext<ApplicationDbContext>((provider, options) => {
|
||||
options
|
||||
.UseSqlite(dbConnection)
|
||||
.UseProjectables()
|
||||
.UseLoggerFactory(LoggerFactory.Create(builder => builder.AddConsole()));
|
||||
.UseInternalServiceProvider(provider);
|
||||
})
|
||||
.BuildServiceProvider();
|
||||
|
||||
|
||||
@@ -10,8 +10,6 @@ namespace EntityFrameworkCore.Projectables.Extensions
|
||||
{
|
||||
public static class ExpressionExtensions
|
||||
{
|
||||
static ProjectableExpressionReplacer _projectableExpressionReplacer = new ProjectableExpressionReplacer(new ProjectionExpressionResolver());
|
||||
|
||||
[Obsolete("Use ExpandProjectables instead")]
|
||||
public static Expression ExpandQuaryables(this Expression 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
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using EntityFrameworkCore.Projectables.Extensions;
|
||||
using EntityFrameworkCore.Projectables.Services;
|
||||
using Microsoft.EntityFrameworkCore.Query;
|
||||
|
||||
@@ -24,17 +22,4 @@ namespace EntityFrameworkCore.Projectables.Infrastructure.Internal
|
||||
public QueryTranslationPreprocessor Create(QueryCompilationContext 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());
|
||||
}
|
||||
}
|
||||
@@ -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"); ;
|
||||
}
|
||||
|
||||
var decoratorObjectFactory = ActivatorUtilities.CreateFactory(typeof(CustomQueryProvider), new[] { targetDescriptor.ServiceType });
|
||||
var decoratorObjectFactory = ActivatorUtilities.CreateFactory(typeof(CustomQueryCompiler), new[] { targetDescriptor.ServiceType });
|
||||
|
||||
services.Replace(ServiceDescriptor.Describe(
|
||||
targetDescriptor.ServiceType,
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace EntityFrameworkCore.Projectables.FunctionalTests.Helpers
|
||||
|
||||
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 => {
|
||||
options.CompatibilityMode(_compatibilityMode); // Needed by our ComplexModelTests
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user