oracle / oracle/dotnet-db-samples
Feature Request: Translate string.Join to LISTAGG
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 434
- Forks
- 191
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 1
Description
Since EF Core 7 automatic translation from string.Join to STRING_AGG in MSSQL Server is supported.
Can a similar translation be supported by the Oracle provider to use LISTAGG?
Example Program:
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
[Table("EMP")]
internal class Employee
{
[Key]
[Column("EMPNO")]
public int EmpNo { get; set; }
[Column("ENAME")]
public string Name { get; set; }
[Column("JOB")]
public string Job { get; set; }
[Column("HIREDATE")]
public DateTime HireDate { get; set; }
[Column("DEPTNO")]
public int DeptNo { get; set; }
[ForeignKey(nameof(DeptNo))]
public virtual Department Department { get; set; }
}
[Table("DEPT")]
internal class Department
{
[Key]
[Column("DEPTNO")]
public int DeptNo { get; set; }
[Column("DNAME")]
public string Name { get; set; }
[Column("LOC")]
public string Location { get; set; }
public virtual ICollection<Employee> Employees { get; set; }
}
internal class ReproContext : DbContext
{
public DbSet<Department> Departments { get; set; }
public DbSet<Employee> Employees { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
var connStr = "TODO";
optionsBuilder.UseOracle(connStr, ora => ora.UseOracleSQLCompatibility(OracleSQLCompatibility.DatabaseVersion19));
}
}
internal class Program
{
public static async Task Main(string[] args)
{
var ctx = new ReproContext();
var queryable = ctx.Departments
.Where(d => d.Name == "RESEARCH")
.Select(d => string.Join(',', d.Employees.OrderBy(e => e.Name).Select(e => e.Name)));
Console.WriteLine(queryable.ToQueryString());
var employeeNames = await queryable.SingleAsync();
Console.WriteLine($"Result: {employeeNames}");
}
}
The generated query is:
SELECT "d"."DEPTNO", "e"."ENAME", "e"."EMPNO"
FROM "DEPT" "d"
LEFT JOIN "EMP" "e" ON "d"."DEPTNO" = "e"."DEPTNO"
WHERE "d"."DNAME" = N'RESEARCH'
ORDER BY "d"."DEPTNO", "e"."ENAME"
Expected query would be:
SELECT LISTAGG("e"."ENAME", ',') WITHIN GROUP (ORDER BY "e"."ENAME")
FROM "DEPT" "d"
LEFT JOIN "EMP" "e" ON "d"."DEPTNO" = "e"."DEPTNO"
WHERE "d"."DNAME" = N'RESEARCH'
Related:
https://forums.oracle.com/ords/apexds/post/efcore-and-listagg-7389
https://github.com/dotnet/efcore/issues/2981
https://github.com/dotnet/efcore/pull/28110
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the ReproContext query using UseOracle and compare its generated SQL with the expected LISTAGG query in the issue. Trace how the Oracle provider handles string.Join, ordering, grouping, and aggregate translation; done means the example produces LISTAGG with the requested separator and ORDER BY semantics.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, sql
- Domain
- backend, databases
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100