【问题标题】:Could not parse expression '…: The given arguments did not match the expected arguments”无法解析表达式'...:给定的参数与预期的参数不匹配”
【发布时间】:2018-09-08 21:16:02
【问题描述】:

我正在使用框架核心 2.0 实体的 CompiledQueries 功能,但即使它没有给出语法错误,当程序运行时,我也会收到此异常:

"Could not parse expression 'value (Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1 [TaskManager.Entities.EntitiesDB.USER]) AsNoTracking (). where (__ conditions)': 给定的参数不匹配预期参数:“System.Linq.Expressions.TypedParameterExpression”类型的对象无法转换为“System.Linq.Expressions.LambdaExpression”类型。”

我不知道它是什么。我需要帮助。

这是显示此错误的存储库的源代码:

    /// <summary>
    /// Query of user
    /// </summary>
    /// <param name="_context">context</param>
    /// <param name="conditions">conditions for clause "Where"</param>
    /// <returns>first task that meets the conditions or null </returns>
    private static Func<Context, Func<USER, bool>, Task<UserResponseDTO>> 
           _getUser = EF.CompileAsyncQuery (
               (Context _context, Func<USER, bool> conditions) =>
                  (conditions == null)? 
                      _context.USER.Select(user =>
                          new UserResponseDTO {
                            NAME = user.NAME,
                            EMAIL = user.EMAIL,
                            SEQUSER = user.SEQUSER,
                            DATEREGISTER = user.DATEREGISTER
                          }
                       ).AsNoTracking().FirstOrDefault ()
                  :                                        
                      _context.USER.AsNoTracking()
                      .Where(conditions).Select(user =>
                          new UserResponseDTO {
                            NAME = user.NAME,
                            EMAIL = user.EMAIL,
                            SEQUSER = user.SEQUSER,
                            DATEREGISTER = user.DATEREGISTER
                          }
                       ).FirstOrDefault ()
           );

我实现 DbContext 的类:

public class Context: DbContext
{
    public Context(DbContextOptions<Context> options): base(options){ }
    public virtual DbSet<USER> USER { get; set; }
    public virtual DbSet<TASK> TASK { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder){
        #region Sequences

        modelBuilder.HasSequence<long> 
        ("S_SEQUSER").StartsAt(1).HasMin(1);
        modelBuilder.HasSequence<long> 
        ("S_SEQTASK").StartsAt(1).HasMin(1);                   

        #endregion

        #region propeties Mapping
        modelBuilder.Entity<USER>()
            .Property(u => u.SEQUSER)                
            .HasDefaultValueSql(" nextval('\"S_SEQUSER\"') ");

        modelBuilder.Entity<TASK>()
           .Property(u => u.SEQTASK)            
           .HasDefaultValueSql(" nextval('\"S_SEQTASK\"') ");

        modelBuilder.Entity<USER>()
        .HasMany(u => u.TASK)
        .WithOne(u => u.USER);   
        #endregion        

        base.OnModelCreating(modelBuilder);
    }
}

我的数据库实体:

/// <summary>
/// query user
/// </summary>
[Table(@"USER")]
public class USER
{
    #region Properties
    /// <summary>
    /// sequence of user
    /// </summary>
    /// <value></value>
    [Key()]
    [Column(@"SEQUSER")]
    public virtual long SEQUSER { get; set; }

    /// <summary>
    /// email of user
    /// </summary>
    /// <value></value>
    [Required]
    [StringLength(120)]
    [Column(@"EMAIL")]
    public virtual string EMAIL { get; set; }

    /// <summary>
    /// password of user
    /// </summary>
    /// <value></value>
    [Required]
    [StringLength(15)]
    [Column(@"PASSWORD")]
    public virtual string PASSWORD { get; set; }

    /// <summary>
    /// name of user
    /// </summary>
    /// <value></value>
    [Required]
    [StringLength(120)]
    [Column(@"NAME")]
    public virtual string NAME { get; set; }        

    /// <summary>
    /// date of user was registered
    /// </summary>
    /// <value></value>
    [Column(@"DATEREGISTER")]
    public virtual DateTime DATEREGISTER { get; set; }

    /// <summary>
    /// last acess of user in application
    /// </summary>
    /// <value></value>
    [Column(@"LASTACESS")]
    public virtual DateTime LASTACESS { get; set; }

    /// <summary>
    /// list of task 
    /// </summary>
    /// <value></value>
    [InverseProperty("USER")]
    public virtual List<TASK> TASK { get; set; }

    #endregion    
}

有人可以帮我解决这个问题吗?

【问题讨论】:

  • CompileQuery[Async] 方法很可能不期望委托作为参数(TParam1TParam2 等)。无论如何这都不好,因为即使它有效,使用它的分支 (.Where(conditions)) 也会检索整个表并在内存中执行过滤。
  • 我写了另一个单独的测试,问题似乎是 Func 作为参数传递。似乎不可能让我的“where”子句保持动态。当我编写一个固定了“Where”子句的 CompiledQuerie 时,它​​可以工作。
  • 它似乎也不适用于像 "?:" (If / else) 这样的运算符。

标签: c# asp.net-core .net-core entity-framework-core


【解决方案1】:

试着把它分解。

从一个简单的测试用例开始(比如一些虚拟的new UserResponseDTO),然后尝试一个简单的静态选择(选择一个特定的用户),然后添加 if/else 条件并尝试使用和不使用conditions,然后向您的第一个 if/else 分支添加一个简单的静态选择,然后对第二个分支执行相同的操作,直到您得到您现在拥有的语句。

您也可以先进行选择(不带 if/else),以检查您的问题是否在上下文定义中。也许在包含" nextval('\"S_SEQUSER\"') "" nextval('\"S_SEQTASK\"') " 的行之一中。顺便说一句:为什么这里有空格?

介于两者之间,会出现问题。不同之处在于:现在您知道在哪里了 ;-)

并且一定要为此编写一个单元测试。通常只需单击鼠标右键即可。

【讨论】:

  • 这是因为我在 postgressql 数据库中使用 CodeFirst,并且我将其作为主键的默认值和我的序列的下一个值,即使从上下文中删除这些行,问题仍然存在
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-06-28
  • 1970-01-01
  • 2021-08-05
  • 2016-07-13
  • 1970-01-01
  • 1970-01-01
  • 2018-09-02
相关资源
最近更新 更多