question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Filtering over Sql.ExpressionMethod alike property having aggregate complex expression

See original GitHub issue

Hi,

Similar to Sql.ExpressionMethod we have construct to create expressions assigned to scalar property. Grids are normally shown with this expression and it works fine, problem is when we want to filter this subquery linq Expression, e.g. . …where ChecklistTriggers like ‘%Hired%’ (ChecklistTrigger defined below)

We are having hundreds of Expressions for properties and we have issues with few of them using Association.Any + StringAggregate. If we remove checklist.ChecklistTriggers.Any call, it is working fine, but that is not correct for our business logic.

public <Func<Checklist, string>> ChecklistTriggers
{
      return checklist => checklist.ChecklistTriggers.Any()
          ? checklist.ChecklistTriggers.AsQueryable()
              .Select(x => x.TriggerType == TriggerType.Hired ? "Hired" :
                   x.TriggerType == TriggerType.PreHired ? "PreHired" :
                   x.TriggerType == TriggerType.Terminated ? "Terminated" : ""
              )
              .StringAggregate(",").ToValue()
           : "None";
}

For version 3.2.3. we get “The method or operation is not implemented.” and for 3.4.5. we get “Cannot perform an aggregate function on an expression containing an aggregate or a subquery.”. Query for 3.4.5. version seems complicated, instead of using subquery, it is duplicated for filter and for normal grid column, strange.

Using Coalesce did not help, the same error.

public <Func<Checklist, string>> ChecklistTriggers
{
      return checklist => checklist.ChecklistTriggers.AsQueryable()
              .Select(x => x.TriggerType == TriggerType.Hired ? "Hired" :
                   x.TriggerType == TriggerType.PreHired ? "PreHired" :
                   x.TriggerType == TriggerType.Terminated ? "Terminated" : ""
              )
              .StringAggregate(",").ToValue() ?? "None";
}

Environment details

linq2db version: 3.2.3. and 3.4.5. Database Server: Sql Server 2019 Database Provider: SQL Operating system: W10 .NET Framework: 4.8.2

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:10 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
zbrkiccommented, Oct 13, 2021

Hi, here is an example:

using LinqToDB;
using LinqToDB.Mapping;
using System.Collections.Generic;
using System.Linq;

namespace Linq2dbTest
{
    public class FilteringTest
    {
        public void Test()
        {
            var builder = MappingSchema.Default.GetFluentMappingBuilder();

            builder.Entity<Checklist>()
                .HasTableName("Checklist")
                .HasSchemaName("Onboarding")
                .Property(x => x.Id).HasColumnName("ChecklistId").IsPrimaryKey()
                .Association(x => x.ChecklistTriggers, x => x.Id, x => x.ChecklistId, canBeNull: false);


            builder.Entity<ChecklistTrigger>()
                .HasTableName("ChecklistTriggers")
                .HasSchemaName("Onboarding")
                .HasIdentity(x => x.Id)
                .HasPrimaryKey(x => x.Id);


            using (var db = new Db())
            {
                var query = db.Checklist
                    .Select(x => new
                    {
                        x.Id,
                        Triggers = x.ChecklistTriggers.Any()
                            ? x.ChecklistTriggers.AsQueryable()
                                .Select(checklist => checklist.TriggerType == TriggerType.Hired ? "Hired" :
                                    checklist.TriggerType == TriggerType.PreHired ? "PreHired" :
                                    checklist.TriggerType == TriggerType.Terminated ? "Terminated" : "")
                                .StringAggregate(",").ToValue()
                        : "None"
                    });

                var good = query.ToList();
                var bad = query.Where(x => x.Triggers.Contains("H")).ToList();
            }
        }

        public class Db: LinqToDB.Data.DataConnection
        {
            public Db() : base(ProviderName.SqlServer2017, "data source=localhost;initial catalog=xxx;integrated security=True;MultipleActiveResultSets=True") { }
            public ITable<Checklist> Checklist => GetTable<Checklist>();
            public ITable<ChecklistTrigger> ChecklistTrigger => GetTable<ChecklistTrigger>();
        }

        public class Checklist
        {
            public virtual int Id { get; set; }
            public virtual ICollection<ChecklistTrigger> ChecklistTriggers { get; set; }
        }

        public class ChecklistTrigger
        {
            public virtual int Id { get; set; }
            public virtual int ChecklistId { get; set; }
            public virtual TriggerType TriggerType { get; set; }
        }

        public enum TriggerType
        {
            Hired = 1,
            PreHired = 2,
            Terminated = 3
        }
    }
}
1reaction
MaceWinducommented, Nov 5, 2021

Probably next thursday

Read more comments on GitHub >

github_iconTop Results From Across the Web

SQL Server complex aggregate filtering
You can apply conditional aggregation if the voltage never goes above 2.5, then below 1.5 and then increases above 1.5 again:
Read more >
SQL HAVING Clause with Examples
The HAVING clause was introduced in SQL to allow the filtering of query results based on aggregate functions and groupings, which cannot be ......
Read more >
How to Filter Records with Aggregate Function COUNT
To filter records according the given number of rows in the group, use the HAVING clause. It filters rows using in a condition...
Read more >
Learn SQL: Aggregate Functions
Aggregate functions are a very powerful tool in databases. They serve the same purpose as their equivalents in MS Excel.
Read more >
How to Aggregate Data Using Group By in SQL [Updated]
Group By in SQL helps us club together identical rows present in the columns of a table. This is an essential statement in...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found