rivantsov / vita

VITA Application Framework
MIT License
59 stars 15 forks source link

ViewHelper.EntitySet #217

Closed rubenalves closed 1 year ago

rubenalves commented 1 year ago

Hello,

I have used ViewHelper.EntitySet in a old project and i canot find eny examples oh how to use it, can you point me for any examples i can analise if?

Thanks.

rivantsov commented 1 year ago

https://github.com/rivantsov/vita/blob/master/src/1.Framework/Vita/4.Internals/Entities.Model/ViewsSequencies.cs

at the very end of the file

rubenalves commented 1 year ago

I explained it wrong, i was loging on a example on how to create views, like,

var docs = ViewHelper.EntitySet(); var query = from d in docs where d.Saldo > 0 select new { ID = d.Id, EntidadeID = d.Entidade.ID, EntidadeNome = d.Entidade.Nome, DataDocumento = d.DataDocumento, Saldo = d.Saldo }; RegisterView(query, DbViewOptions.Materialized);

Do you have any examples like this? is it possible to make aggregate values?

Thanks, sorry for not explaing it bat.

rivantsov commented 1 year ago

There are several views defined in BooksModule.cs in BookStore project in Samples folder I think you can use Linq stuff, including aggregations/grouping

rubenalves commented 1 year ago

Problem solved, Thanks.

rubenalves commented 1 year ago

I have it working, is there any way to force the view to use default values?

Ex. QtdEnt01 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Entradas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 1).Sum(bol => bol.Quantidade),

Column QtdEnt01 is NULL, is there a way to make it be the default value? 0 for 0.00 for decimal?

Thanks.

rivantsov commented 1 year ago

as far as I understand, you get null value because there's no rows to Sum? then just check it for null and replace with 0 (if we are talking about c#). Or just add at the end (expr) ?? 0; If it is something in lower level, inspect the SQL, run it manually in SqlMgmtStudio, see what it returns, and can it be handled (there's COALESCE function I think) Otherwise I need more context here

rubenalves commented 1 year ago

Yes, it is null when there is nothing to sum, is it possible to do on the ViewDefinition?

Here is a Example:

var artigos = ViewHelper.EntitySet(); var acumulados = ViewHelper.EntitySet(); var precos = ViewHelper.EntitySet(); var lanSet = ViewHelper.EntitySet(); var query = from p in precos join art in artigos on p.Artigo.ID equals art.ID into artGroup from art in artGroup.DefaultIfEmpty() join acum in acumulados on art.ID equals acum.Artigo.ID into acumGroup from ac in acumGroup select new { ac.Ano, Artigo = art.Designacao, Codigo = art.Codigo, Entradas = lanSet.Where(a => a.Artigo == art && a.TipoMovimento == TiposMovimento.Entradas && a.DataRegisto.Year == ac.Ano).Sum(bol => bol.Quantidade), Compras = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Compras && a.DataRegisto.Year == ac.Ano).Sum(bol => bol.Quantidade), Saidas = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Saidas && a.DataRegisto.Year == ac.Ano).Sum(bol => bol.Quantidade), Vendas = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Vendas && a.DataRegisto.Year == ac.Ano).Sum(bol => bol.Quantidade), Saldo = lanSet.Where(a => a.Artigo == art && a.TipoMovimento == TiposMovimento.Entradas && a.DataRegisto.Year == ac.Ano).Sum(bol => bol.Quantidade) + lanSet.Where(a => a.Artigo == art && a.TipoMovimento == TiposMovimento.Compras && a.DataRegisto.Year == ac.Ano).Sum(bol => bol.Quantidade) - lanSet.Where(a => a.Artigo == art && a.TipoMovimento == TiposMovimento.Saidas && a.DataRegisto.Year == ac.Ano).Sum(bol => bol.Quantidade) - lanSet.Where(a => a.Artigo == art && a.TipoMovimento == TiposMovimento.Vendas && a.DataRegisto.Year == ac.Ano).Sum(bol => bol.Quantidade), QtdEnt01 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Entradas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 1).Sum(bol => bol.Quantidade), QtdEnt02 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Entradas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 2).Sum(bol => bol.Quantidade), QtdEnt03 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Entradas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 3).Sum(bol => bol.Quantidade), QtdEnt04 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Entradas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 4).Sum(bol => bol.Quantidade), QtdEnt05 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Entradas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 5).Sum(bol => bol.Quantidade), QtdEnt06 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Entradas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 6).Sum(bol => bol.Quantidade), QtdEnt07 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Entradas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 7).Sum(bol => bol.Quantidade), QtdEnt08 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Entradas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 8).Sum(bol => bol.Quantidade), QtdEnt09 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Entradas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 9).Sum(bol => bol.Quantidade), QtdEnt10 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Entradas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 10).Sum(bol => bol.Quantidade), QtdEnt11 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Entradas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 11).Sum(bol => bol.Quantidade), QtdEnt12 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Entradas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 12).Sum(bol => bol.Quantidade), QtdVend01 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Vendas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 1).Sum(bol => bol.Quantidade), QtdVend02 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Vendas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 2).Sum(bol => bol.Quantidade), QtdVend03 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Vendas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 3).Sum(bol => bol.Quantidade), QtdVend04 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Vendas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 4).Sum(bol => bol.Quantidade), QtdVend05 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Vendas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 5).Sum(bol => bol.Quantidade), QtdVend06 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Vendas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 6).Sum(bol => bol.Quantidade), QtdVend07 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Vendas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 7).Sum(bol => bol.Quantidade), QtdVend08 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Vendas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 8).Sum(bol => bol.Quantidade), QtdVend09 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Vendas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 9).Sum(bol => bol.Quantidade), QtdVend10 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Vendas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 10).Sum(bol => bol.Quantidade), QtdVend11 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Vendas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 11).Sum(bol => bol.Quantidade), QtdVend12 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Vendas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 12).Sum(bol => bol.Quantidade), QtdSai01 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Saidas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 1).Sum(bol => bol.Quantidade), QtdSai02 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Saidas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 2).Sum(bol => bol.Quantidade), QtdSai03 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Saidas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 3).Sum(bol => bol.Quantidade), QtdSai04 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Saidas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 4).Sum(bol => bol.Quantidade), QtdSai05 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Saidas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 5).Sum(bol => bol.Quantidade), QtdSai06 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Saidas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 6).Sum(bol => bol.Quantidade), QtdSai07 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Saidas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 7).Sum(bol => bol.Quantidade), QtdSai08 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Saidas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 8).Sum(bol => bol.Quantidade), QtdSai09 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Saidas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 9).Sum(bol => bol.Quantidade), QtdSai10 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Saidas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 10).Sum(bol => bol.Quantidade), QtdSai11 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Saidas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 11).Sum(bol => bol.Quantidade), QtdSai12 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Saidas && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 12).Sum(bol => bol.Quantidade), QtdComp01 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Compras && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 1).Sum(bol => bol.Quantidade), QtdComp02 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Compras && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 2).Sum(bol => bol.Quantidade), QtdComp03 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Compras && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 3).Sum(bol => bol.Quantidade), QtdComp04 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Compras && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 4).Sum(bol => bol.Quantidade), QtdComp05 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Compras && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 5).Sum(bol => bol.Quantidade), QtdComp06 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Compras && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 6).Sum(bol => bol.Quantidade), QtdComp07 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Compras && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 7).Sum(bol => bol.Quantidade), QtdComp08 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Compras && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 8).Sum(bol => bol.Quantidade), QtdComp09 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Compras && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 9).Sum(bol => bol.Quantidade), QtdComp10 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Compras && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 10).Sum(bol => bol.Quantidade), QtdComp11 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Compras && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 11).Sum(bol => bol.Quantidade), QtdComp12 = lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Compras && a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 12).Sum(bol => bol.Quantidade), };

    RegisterView<IAcumArt>(query, DbViewOptions.None,  "ArtigosAcum");

Tnaks.

rivantsov commented 1 year ago

wow, that's some View .... and you say it produces correct SQL? wow try adding " ?? 0,0 " after the Sum; it should be translated into Coalesce(sum, 0.0) in SQL

rubenalves commented 1 year ago

Yes, it produces the correct SQL, I canot add ?? 0 because it does not compile.

rivantsov commented 1 year ago

put all preceding expression starting from IanSet into parenthesis:

QtdComp12 = (
    lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Compras && 
            a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 12).Sum(bol => bol.Quantidade)
) ?? 0.0m,

if 'does not compile', tell me the error

rubenalves commented 1 year ago

It does not compile, gives a error.

Operator ?? canot be applied to of type decimal and decimal

Left operatior of the ?? operator must be of reference or nullable type

That is the i get in visual studio.

rivantsov commented 1 year ago

ah, get it. just for experiment, put "?" before the .Sum:

QtdComp12 = (
    lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Compras && 
            a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 12)?.Sum(bol => bol.Quantidade)
) ?? 0.0m,
rubenalves commented 1 year ago

Does not compile.

rivantsov commented 1 year ago

again, what's the error?

rubenalves commented 1 year ago

Severity Code Description Project File Line Suppression State Error CS8072 An expression tree lambda may not contain a null propagating operator. TsGest.DL C:\Dropbox\TerceiraSoft\2021\TsGest\TsGest.DL\TsGestModules\TsGestModule.cs 151 Active

That is th error.

rivantsov commented 1 year ago

Ok, let's try to use custom code snippet to inject IsNull call into SQL. First, have a look at example of defining snippet, in test file MiscTests_Model.cs, in basic tests, at the very end, function DbAddYears:

https://github.com/rivantsov/vita/blob/e75092425283fe396ef25b94e01b6959dd04fcbb/src/6.UnitTests/Vita.Testing.BasicTests/MiscTests_Model.cs#L138

We will try to do something like this for IsNull function in MsSqL. Define the following ext method in a static file:

    // MS SQL IsNull function: https://www.w3schools.com/sql/func_sqlserver_isnull.asp
    [SqlExpression(DbServerType.MsSql, "ISNULL({value}, 0)")]
    public static Decimal NullAsZero(this Decimal value) {
      CannotCallDirectly();
      return default;
    }

    private static void CannotCallDirectly([CallerMemberName] string methodName = null) {
      throw new NotImplementedException(
        $"Function '{methodName}' may not be called directly, only in LINQ expressions.");
    }
rivantsov commented 1 year ago

continued, pushed Post by accident, sorry

now, call this NullAsZero on the result of sum:

QtdComp12 =   lanSet.Where(a => a.Artigo == art && a.MovimentaStock && a.TipoMovimento == TiposMovimento.Compras &&  
a.DataRegisto.Year == ac.Ano && a.DataRegisto.Month == 12).Sum(bol => bol.Quantidade) 
.NullAzZero();

let's try this; the resulting SQL should have this IsNull() call around Sum

rubenalves commented 1 year ago

it does not work, gives this error: Function NullAsZero not supported in queries

I will try to alterar the view after vita created it, will informe you of the result.

rivantsov commented 1 year ago

I missed one thing, you need to register the class containing this function, in the module constructor where you register all entity types:

  mainModule.RegisterFunctions(typeof(YOUR_CLASS_WITH_EXT_METHOD));

See BooksModule for example

Correction: you can do it module constructor or in EntityApp constructor, as in Books sample app

rubenalves commented 1 year ago

It works, You are The MAN.

Thanks for making the best ORM ever.

rivantsov commented 1 year ago

Yaaay!!! congrats!