Breeze "IN" 运算符导致服务器端错误

Breeze "IN" operator causes server side error

我正在编写一个 Web 应用程序,前端使用 angular,数据 management/middle 层使用 Breeze,服务器端使用 ASP.net 核心和 EFCore .

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

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

在客户端,我有一个 breeze 查询,如下所示:

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<string>VerbID 是一个 Int 并且我传入一个 Ints.

的数组

如果我将 client-side 查询更改为:

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 源代码以查看它是否是错误之前告诉我我是否做错了什么。

这是供参考的server-side代码,如您所见,我除了包装breeze ASP.net Core/EF Core server-side东西。

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) { }
}

我做了一些挖掘,这绝对是一个错误,或者更具体地说,“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);
}

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