Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot access property through interface in ExecuteUpdate setter lambda #29618

Closed
xuejmnet opened this issue Nov 19, 2022 · 7 comments · Fixed by #29672
Closed

Cannot access property through interface in ExecuteUpdate setter lambda #29618

xuejmnet opened this issue Nov 19, 2022 · 7 comments · Fixed by #29672
Assignees
Labels
area-bulkcud closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported Servicing-approved type-bug
Milestone

Comments

@xuejmnet
Copy link

lib

      <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.0" />
      <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="7.0.0-alpha.1" />

code

           //success
            await _ncdcDbContext.Set<LogicDatabaseEntity>().Where(o => o.Id == id).ExecuteUpdateAsync(o => o.SetProperty(p => p.IsDelete, p => true));
          //error
            await _ncdcDbContext.Set<LogicDatabaseEntity>().Where(o => o.Id == id).LogicDeleteAsync();

public static class QueryableExtension
{
    public static Task<int> LogicDeleteAsync<T>(this IQueryable<T> queryable) where T:ILogicDelete
    {
        return queryable.ExecuteUpdateAsync(o => o.SetProperty(p => p.IsDelete, p => true));
    }
}


public interface ILogicDelete
{
    bool IsDelete { get; set; }
}

public class LogicDatabaseEntity:ILogicDelete
{
    public string DatabaseName { get; set; } = null!;
    public bool IsDelete { get; set; }

}

error

The LINQ expression 'DbSet<LogicDatabaseEntity>()
          .Where(l => l.IsDelete == False)
          .Where(l => l.Id == __id_0)
          .ExecuteUpdate(o => o.SetProperty<bool>(
              propertyExpression: p => ((ILogicDelete)p).IsDelete, 
              valueExpression: p => True))' could not be translated. Additional information: The following lambda argument to 'SetProperty' does not represent a valid property to be set: 'p => ((ILogicDelete)p).IsDelete'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
      System.InvalidOperationException: The LINQ expression 'DbSet<LogicDatabaseEntity>()
          .Where(l => l.IsDelete == False)
          .Where(l => l.Id == __id_0)
          .ExecuteUpdate(o => o.SetProperty<bool>(
              propertyExpression: p => ((ILogicDelete)p).IsDelete, 
              valueExpression: p => True))' could not be translated. Additional information: The following lambda argument to 'SetProperty' does not represent a valid property to be set: 'p => ((ILogicDelete)p).IsDelete'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
         at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
         at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
         at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
         at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
         at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
         at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
         at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass12_0`1.<ExecuteAsync>b__0()
         at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
         at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.RelationalQueryableExtensions.ExecuteUpdateAsync[TSource](IQueryable`1 source, Expression`1 setPropertyCalls, CancellationToken cancellationToken)
         at NCDC.EntityFrameworkCore.QueryableExtension.LogicDeleteAsync[T](IQueryable`1 queryable) in /Users/xuejiaming/Desktop/githubs/OpenConnector/src/orm/NCDC.EntityFrameworkCore/QueryableExtension.cs:line 8
         at NCDC.WebBootstrapper.Controllers.LogicDatabase.LogicDatabaseController.Delete(String id) in /Users/xuejiaming/Desktop/githubs/OpenConnector/src/bootstrapper/NCDC.WebBootstrapper/Controllers/LogicDatabase/LogicDatabaseController.cs:line 104
         at lambda_method235(Closure , Object )
         at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
@ErikEJ
Copy link
Contributor

ErikEJ commented Nov 19, 2022

You need to share a runnable code sample

@xuejmnet
Copy link
Author

@ErikEJ demo

@xuejmnet
Copy link
Author

image

@xuejmnet
Copy link
Author

im push new code for code sample

@roji
Copy link
Member

roji commented Nov 19, 2022

This is because of the access of the property through the interface in the SetProperty key lambda: p => ((ILogicDelete)p).IsDelete. Property setter lambdas are currently very constrained in the type of expressions the allow.

If you replace your extension method:

public static Task<int> LogicDeleteAsync<T>(this IQueryable<T> queryable) where T:ILogicDelete
{
    return queryable.ExecuteUpdateAsync(o => o.SetProperty(p => p.IsDelete, p => true));
}

... with a non-generic version:

public static Task<int> LogicDeleteAsync2(this IQueryable<LogicDatabaseEntity> queryable)
{
    return queryable.ExecuteUpdateAsync(o => o.SetProperty(p => p.IsDelete, p => true));
}

... then everything works. Flagging as a bug.

@roji roji changed the title ExecuteUpdate BUG in Extension method Cannot access property through interface in ExecuteUpdate setter lambda Nov 19, 2022
@xuejmnet
Copy link
Author

@roji yes support generic is importment for project,it make code robust

@ajcvickers ajcvickers added this to the 8.0.0 milestone Nov 23, 2022
roji added a commit to roji/efcore that referenced this issue Nov 24, 2022
@roji roji added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Nov 24, 2022
roji added a commit to roji/efcore that referenced this issue Nov 25, 2022
Referencing unowned properties only for now.

Fixes dotnet#29618
roji added a commit that referenced this issue Nov 30, 2022
@roji roji removed this from the 8.0.0 milestone Nov 30, 2022
@roji
Copy link
Member

roji commented Nov 30, 2022

Clearing milestone to discuss patching

@roji roji reopened this Nov 30, 2022
roji added a commit to roji/efcore that referenced this issue Dec 1, 2022
@ajcvickers ajcvickers added this to the 7.0.x milestone Dec 5, 2022
@ajcvickers ajcvickers modified the milestones: 7.0.x, 7.0.3 Jan 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-bulkcud closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported Servicing-approved type-bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants