brunobritodev / aspnetcore.iqueryable.extensions Goto Github PK
View Code? Open in Web Editor NEWLINQ extensions to help build IQueryAble Expressions
License: MIT License
LINQ extensions to help build IQueryAble Expressions
License: MIT License
Como resolver, pois quando o campo que deseja filtrar está em um objeto de valor da entidade, o filtro não funciona.
public class AuditQuery : ICustomQueryable, IQueryPaging, IQuerySort
{
[QueryOperator(Operator = WhereOperator.Equals, HasName = nameof(CareInfo.InsurerReferenceNumber))]
public string? InsurerReferenceNumber { get; set; }
[QueryOperator(Operator = WhereOperator.Contains, HasName=nameof(Audit.Type))]
public List? Types { get; set; }
[QueryOperator(Operator = WhereOperator.Contains, HasName=nameof(Audit.Status))]
public List? Statuses { get; set; }
public Guid? TeamId { get; set; }
public int? Limit { get; set; } = 25;
public int? Offset { get; set; } = 0;
public string Sort { get; set; } = nameof(Audit.AuditDeadline);
}
public class Audit : Entity, IAggregateRoot
{
public DateTime RecordDate { get; private set; }
public DateTime AuditDeadline { get; private set; }
public RequestSource Source { get; private set; }
public string SourceId { get; private set; }
public AuditType Type { get; private set; }
public BeneficiaryInfo BeneficiaryInfo { get; private set; }
public CareInfo CareInfo { get; private set; }
public bool IsRetrospective { get; private set; }
public bool IsInsistence { get; private set; }
public int InsistenceSequence { get; private set; }
....
}
public class CareInfo
{
public EventType EventType { get; private set; }
public string InsurerReferenceNumber { get; private set; }
public string OriginReferenceNumber { get; private set; }
public DateTime CareDate { get; private set; }
public RequestOrigin RequestOrigin { get; private set; }
}
Problema
Quando é definido o QueryOperator(Max = N) e é definido um valor Limit entre 0 e N, o valor Limit está sendo substituído pelo valor Max, porém essa substituição deveria ocorrer apenas quando o valor Limit não é definido ou é maior que o Max.
File: PagingExtension.cs
if (attr?.GetType() == typeof(QueryOperatorAttribute))
{
var data = (QueryOperatorAttribute)attr;
if (data.Max > 0)
options.Limit = data.Max;
}
Código de correção
File: PagingExtension.cs
if (attr?.GetType() == typeof(QueryOperatorAttribute))
{
var data = (QueryOperatorAttribute)attr;
if (!options.Limit.HasValue)
options.Limit = data.Max;
else if (data.Max > 0 && options.Limit > data.Max)
options.Limit = data.Max;
}
Teste
File: PagingTest.cs
[Fact]
public void Should_Get_Limit_Paging_When_Limit_Is_Less_Than_Max()
{
var paginate = new PagingMax()
{
Limit = 3,
Offset = 0
};
var userList = _users.AsQueryable().Paginate(paginate);
userList.Should().HaveCount(3);
}
Olá, estou tentando realizar uma consulta usando os operadores (em campos dateTime e double) GreaterThanOrEqualTo e/ou LessThanOrEqualTo
Mas estou recebendo os erros:
The binary operator GreaterThanOrEqual is not defined for the types 'System.Nullable`1[System.Double]' and 'System.Double'.
The binary operator LessThanOrEqual is not defined for the types 'System.Nullable`1[System.DateTime]' and 'System.DateTime'.
Abaixo a forma como fiz a implementação:
[QueryOperator(Operator = WhereOperator.GreaterThanOrEqualTo, HasName = "ValorPrincipal")]
public double? ValorPrincipalMaiorIgual { get; set; }
[QueryOperator(Operator = WhereOperator.LessThanOrEqualTo, HasName = "DataVencimento")]
public DateTime? DataVencimentoMenorIgual { get; set; }
Alguma possibilidade de incluir "EqualsNullable", @brunobritodev? A situação acontece quando precisamos passar um valor que pode ou não ser nulo, a partir de um inteiro, long, float ou decimal quando informado como propriedade para uma classe que herde de ICustomQueryable. O @magnodourado abriu um Pull Request #14 para esta situação. Acredito que vale a tentativa inicialmente para os tipos citados, e posteriormente ser um Generic. O que acha? 👌
Have you ever thought about being able to define the type of filter applied dynamically? like, the user has the filter on the grid, which has all the possible options and he chooses what he wants to use. but it is not feasible for me to create about 10 attributes for each property, because each one needs to have a different query operator. there could be one and I would inform by the query string which one I will use.
ex:
[QueryOperator(Operator = WhereOperator.Dynamic, CaseSensitive = false)]
public string? Name { get; set; }
then, the call
https://localhost:7139/api/Supplier?Limit=10&Offset=0&Name=Paul|Contains
I'm unable to sort by Navigation Properties, i.e. I have a sort query "Animal.Category.Name"
And I'm unable to sort by it, because it crashes in PrimitiveExtensions
on PropertyInfo GetProperty<TEntity>(string name)
. GetProperty
only "sees" the properties from the base type.
Could you help me please?
Alguma forma do campo "Sort" da IQuerySort também olhar o parâmetro "HasName" do QueryOperatorAttribute.
Hi
I am not clear on how to use the Filter Extensions dynamically. I have a list of fields and a parameter. The filter is to return a result where any of the fields contains the parameter. How to use the filter please give an example
Please help
thanks
Utilizando a biblioteca, verifiquei que não é possível realizar filtro com propriedade do tipo Guid, de modo que realizei uma análise mais a fundo e constatei que o IQueryableExtension não realiza a consulta. Isto porque a biblioteca possui um método que verifica se a propriedade é um objeto através do Enum TypeCode. Ou seja, quando é passado uma propriedade Guid, a biblioteca entende que está sendo recebido um object e não uma propriedade.
File: PrimitiveExtensions.cs
public static bool IsPropertyObject(this PropertyInfo property, object value)
{
return Convert.GetTypeCode(property.GetValue(value, null)) == TypeCode.Object;
}
Sugestão Código de correção
File: PrimitiveExtensions.cs
public static bool IsPropertyObject(this PropertyInfo property, object value)
{
var isObject = Convert.GetTypeCode(property.GetValue(value, null)) == TypeCode.Object;
if (isObject && IsPropertyGuid(property, value))
return false;
return isObject;
}
public static bool IsPropertyGuid(this PropertyInfo property, object value)
{
var propertyValue = property.GetValue(value, null);
if (propertyValue == null) return false;
return propertyValue.GetType().Name == nameof(Guid);
}
Quando é definido o QueryOperator(Max = N) e é definido um valor Limit entre 0 e N, o valor Limit está sendo substituído pelo valor Max, porém essa substituição deveria ocorrer apenas quando o valor Limit não é definido ou é maior que o Max.
Por exemplo:
public Class Pedido
{
public Guid CentroDistribuicaoId {get; set;}
public virtual CentroDistribuicao {get; set;}
}
public Class CentroDistribuicao
{
public Guid Id {get; set;}
public string Local {get; set;}
}
// Filtro manual
_pedidos.Include(pedido => pedido.CentroDistribuicao);
_pedidos.Where(pedido => pedido.CentroDistribuicao.Local == "SP");
Que seria uma query:
SELECT * FROM Pedido
JOIN CentroDistribuicao ON CentroDistribuicao.Id = Pedido.CentroDistribuicaoId
WHERE CentroDistribuicao.Local = 'SP'
É possível utilizar essa extensão para buscar também com includes?
Caso seja possível, como isso seria feito?
O pacote possui alguma tratativa para quando se deseja que a consulta tenha algum campo como nulo?
Olá, é possível fazer com que um único parâmetro execute o filtro e campos diferentes?
[QueryOperator(Operator = WhereOperator.Contains)]
public string Filtrar { get; set; }
O parâmetro acima realizar o filtro em 3 colunas diferentes na tabela.
Extensions methods públicos em tipos primitivos não é uma prática legal, porque polui objetos e pode até criar conflitos.
Eu não deveria enxergar isso no meu projeto: public static string[] Fields(this string fields)
Seria possivel a adição desse filtro para datas?
Ou conseguiria usar com 2 filtros de <=, < e >=, >?
Gostaria de usar em uma consulta do tipo
await _context.Report.AsNoTracking()
.Include(x => x.Area)
.Include(x => x.Customer)
.Include(x => x.ReportSerialNumbers)
.ThenInclude(y => y.SerialNumber)
.Include(x => x.ApprovalRequest)
.ToListAsync();
Ultilizando uma classe do tipo:
public class ReportQueryableDto : ICustomQueryable, IQueryPaging, IQuerySort
{
public string AreaDescripton { get; set; }
public DateTime? CreateDate { get; set; }
public string CustomerDescripton { get; set; }
public string FullName { get; set; }
[QueryOperator(Operator = WhereOperator.Equals, HasName = "RequestCode")]
public string ReportNumber { get; set; }
public string UserName { get; set; }
public int? Limit { get; set; } = 100;
public int? Offset { get; set; }
public string Sort { get; set; }
}
Onde as propriedades que tem o Description no nome, precisa buscar as informações dentro das tabelas corespondentes
Como eu posso configurar as propriedades do meu modelo de consulta para que duas propriedades executem filtros em uma mesma propriedade da entidade?
Por exemplo em filtros de datas onde se tem data inicial e data final para o range da consulta.
No baixo nível a consulta sql deve gerar um between, mas como eu identifico no meu modelo as duas propriedades para esse filtro?
Boa noite.
Tenho o seguinte cenário:
Tabela: Carros
Tabela CarrosProPrietarios
Tabela: Proprietarios
A tabela CarrosProPrietarios serve para criar o relacionamento entre Carros e Proprietarios.
Utilizando o ICustomQueryable na minha classe de busca de carros, criei o seguinte parâmetro:
[QueryOperator(Operator = WhereOperator.Contains, HasName = "CarrosProPrietarios.Proprietarios.Nome")]
public string NomeProprietario{ get; set; }
Ou seja, quero trazer todos os carros, filtrando pelo nome do proprietário.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.