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);
}
你是对的。我们会研究一下。 ...感谢您找到这个。
我正在编写一个 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);
}
你是对的。我们会研究一下。 ...感谢您找到这个。