【问题标题】:Breeze "IN" operator causes server side errorBreeze“IN”运算符导致服务器端错误
【发布时间】:2021-10-17 22:25:44
【问题描述】:

我正在编写一个 Web 应用程序,前端使用 Angular,数据管理/中间层使用 Breeze,服务器端使用 ASP.net 核心和 EFCore。

我遇到的问题是,似乎在整数字段上使用“IN”运算符创建查询似乎不起作用。

我已将代码简化为重现问题所需的代码。

在客户端,我有一个看起来像这样的微风查询:

import { Injectable } from '@angular/core';
import { EntityManager, EntityQuery, FilterQueryOp, Predicate } from 'breeze-client';
import { Observable, of, from } from 'rxjs';
import { EntityManagerProvider } from './entity-manager-provider';
import { Verb } from './model/verb';

@Injectable({providedIn: 'root'})
export class VerbService {

  manager: EntityManager    

  constructor(private entityManagerProvider: EntityManagerProvider) {
    this.manager = entityManagerProvider.newManager();    
  }

  getVerbs(): Observable<Verb[]> {

    const query = new EntityQuery('Verbs')
      .where("verbID", FilterQueryOp.In, [1, 2, 3]);
    return from(
      this.manager.executeQuery(query)
        .then(data => { return <Verb[]>data.results }));
    }
}

这会产生以下获取请求:

https://localhost:44356/api/breeze/Verbs?{"where":{"VerbID":{"in":[1,2,3]}}}

据我所知是正确的。

问题是这会导致以下错误:

ArgumentException: Method 'Boolean Contains(System.String)'
declared on type 'System.Collections.Generic.List`1[System.String]'
cannot be called with instance of type 'System.Collections.Generic.List`1[System.Int32]'

需要明确的是,与此无关的是字符串或List&lt;string&gt;VerbID 是一个 Int,我传入了一个 Ints 数组。

如果我将客户端查询更改为:

const query = new EntityQuery('Verbs')
      .where("verbID", FilterQueryOp.Equals, 1)
      .orderBy("name");

产生如下所示的请求:

https://localhost:44356/api/breeze/Verbs?{"where":{"VerbID":{"eq":1}}}

它工作正常,我尝试过的所有其他类型的不使用“in”运算符的查询也是如此。

为了清楚起见,请求正确地进行了 URL 转义,我只是将它们取消转义以使其更易于阅读。

在我开始调试 Breeze 源代码以查看它是否是错误之前,我发布此内容只是为了看看是否有人可以建议我是否做错了什么。

这是供参考的服务器端代码,正如您所见,除了包装微风 ASP.net Core/EF Core 服务器端的东西之外,我并没有真正做任何事情。

public class Verb
{
    public int VerbID { get; set; }
    public string Name { get; set; }
    public string Translation { get; set; }
    public string VerbTypeDescription { get; set; }
}

public class VerbsContext : DbContext
{
    public VerbsContext(DbContextOptions<VerbsContext> options) : base(options)
    {
    }

    public DbSet<Verb> Verbs { get; set; }
        
}
[Route("api/[controller]/[action]")]
[BreezeQueryFilter]
public class BreezeController : ControllerBase
{
    private readonly VerbsPersistenceManager _persistenceManager;

    public BreezeController(VerbsContext context)
    {
        _persistenceManager = new VerbsPersistenceManager(context);
    }

    public IQueryable<Verb> Verbs()
    {
        return _persistenceManager.Context.Verbs;
    }        
}

public class VerbsPersistenceManager : EFPersistenceManager<VerbsContext>
{
    public VerbsPersistenceManager(VerbsContext context) : base(context) { }
}

【问题讨论】:

    标签: angular asp.net-core asp.net-web-api breeze


    【解决方案1】:

    你是对的。我们会研究一下。 ...感谢您找到这个。

    【讨论】:

    • 我已经提交了一个带有修复的拉取请求。
    【解决方案2】:

    我已经进行了一些挖掘,这绝对是一个错误,或者更具体地说,“IN”运算符似乎不完整,目前只是一个只适用于字符串的 hack。

    这是 Breeze.Core 源代码中的违规行:

    else if (op == BinaryOperator.In) 
    {
        // TODO: need to generalize this past just 'string'
        var mi = TypeFns.GetMethodByExample((List<String> list) => List.Contains("abc"), expr1.Type);
        return Expression.Call(expr2, mi, expr1);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-06
      • 2011-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多