简体   繁体   中英

Convert from Query postgresql to linq C#

I want work with linq using "groupby" with "string_agg" but i can't find reference from this query.

SELECT DISTINCT "TB_M_GROUP_EMP"."GROUP_ID" AS "ID", 
  string_agg(Distinct "TB_M_EMPLOYEES"."EMP_NAME",',' order by "TB_M_EMPLOYEES"."EMP_NAME" ) as "Employee Name"
FROM public."TB_M_GROUP_EMP", "TB_M_EMPLOYEES"
GROUP BY "TB_M_GROUP_EMP"."GROUP_ID";

or this code

SELECT DISTINCT "TB_M_GROUP_EMP"."GROUP_ID" as "Group Id", array_agg(Distinct"TB_M_EMPLOYEES"."EMP_CODE" || ',' ||"TB_M_EMPLOYEES"."EMP_NAME"|| ',' ||"TB_M_EMPLOYEES"."EMP_EMAIL" ) as "Employees"
FROM public."TB_M_GROUP_EMP", "TB_M_EMPLOYEES"
GROUP BY "TB_M_GROUP_EMP"."GROUP_ID";

please help to convert this query into linq C# and give a reference or documentation linq!

I have tried to use this code but it's not quite what I want the output to be.

groupEmployee
   .GroupBy(e => new { e.GroupId, e.Employee }, (key, group) => new
   {
      Employee = key.Employee,
      Employees = group.ToList()
   })

Example table :

--------------
TB_M_EMPLOYEES
--------------
|EMP_ID|EMP_CODE|EMP_NAME|EMP_EMAIL|
------------------------------------
|1     |E0012   |Ali     |@ali     |
|2     |E0013   |AL      |@al      |
|3     |E0014   |Abi     |@abi     |
|4     |E0015   |Ad      |@ad      |
|5     |E0016   |Ea      |@ea      |

----------------------
TB_M_GROUP_EMP
----------------------
|Id|GROUP_ID|EMP_ID|
----------------------
|1 |1       |1     |
|2 |1       |2     |
|3 |1       |3     |
|4 |1       |4     |
|5 |1       |5     |

from two table in above. i want the output to be the table this bottom.

TB_M_GROUP_EMP
-----------------
|GROUP_ID|EMP|
-----------------
|1       |{"E0012,Ali,@ali","E0013,Al,@al","E0014,Abi,@abi","E0015,Ad,@ad","E0016,Ea,@ea"}|

Thanks.

Check out:

https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.aggregate?view=netcore-3.1

Ex.

items.Aggregate((i, j) => i + delimiter + j));

This likely won't produce the same SQL statement - so you may have to optimise for performance.

Maybe you can type this using LINQ:

var result =
        from employee in groupEmployee
        group employee by employee.GroupId into output
        select output;

And now you have your output in result. For answering your question I used the following article: https://docs.microsoft.com/en-gb/dotnet/csharp/linq/group-query-results

Assuming, we have the following models:

public class Employee
{
    public int EmployeeId { get; set; }
    public string Code { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

public class EmployeeGroup
{
    public int Id { get; set; }
    public int GroupId { get; set; }
    public int EmployeeId { get; set; }
}

Try, the below:

var result = groups
    .Join(employees, grp => grp.EmployeeId, emp => emp.EmployeeId, (group, employee) => 
        new
        {
            group.GroupId,
            employee.EmployeeId,
            employee.Code,
            employee.Name,
            employee.Email,
        })
    .GroupBy(res => res.GroupId)
    .Select(res => new
    {
        GroupId = res.Key,
        Names = string.Join(",", res
                        .OrderBy(e => e.Name)
                        .Select(e => $"{e.Code},{e.Name},{e.Email}"))
    })
    .ToList();

Yet, another verson here could be (maybe more close to the output you want):

var result = groups.GroupJoin(employees, grp => grp.EmployeeId, emp => emp.EmployeeId,
    (grp, emp) => new
    {
        grp.GroupId,
        Names = string.Join(",", emp.Select(e => $"{e.Code},{e.Name},{e.Email}"))
    }).
    GroupBy(e=> e.GroupId)
    .ToList();

If you want the ordered (by name) version for the above, then the query can become a bit more complex:

var result = groups
    .GroupJoin(employees,
        grp => grp.EmployeeId,
        emp => emp.EmployeeId,
        (grp, emps) =>
        {
            var empsList = emps.ToList();

            return new
            {
                grp.GroupId,
                NamesCmp = empsList.Select(e => e.Name).FirstOrDefault(), // this needed for Ordering
                Names = string.Join(",", empsList.Select(e => $"{e.Code},{e.Name},{e.Email}"))
            };
        })
    .GroupBy(e => e.GroupId)
    .Select(grp => new
    {
        GroupId = grp.Key,
        Items = grp.OrderBy(g => g.NamesCmp)
            .Select(g => g.Names)
    })
    .ToList();

Please note that using real class models for the above instead of anonymous types is more preferable.

Based on my understanding you are looking for below solution. If I missed something then please let me know.

  1. First Join two tables based on EMP_ID
  2. Group by GROUP_ID column.
  3. Use string.Join to join $""{e.EMP_CODE},{e.EMP_NAME},{e.EMP_EMAIL}"".

Below is the code:

var result = (from empRow in TB_M_EMPLOYEES.AsEnumerable()
                      join grpRow in TB_M_GROUP_EMP.AsEnumerable()
                      on empRow.Field<string>("EMP_ID") equals grpRow.Field<string>("EMP_ID")
                      select new
                      {
                          EMP_ID = empRow.Field<string>("EMP_ID"),
                          EMP_CODE = empRow.Field<string>("EMP_CODE"),
                          EMP_NAME = empRow.Field<string>("EMP_NAME"),
                          EMP_EMAIL = empRow.Field<string>("EMP_EMAIL"),
                          GROUP_ID = grpRow.Field<string>("GROUP_ID")
                      }).GroupBy(r => r.GROUP_ID)
                        .Select(rs => new
                        {
                            GroupId = rs.Key,
                            FinalNames = string.Join(",", rs
                                            .Select(e => $"\"{e.EMP_CODE},{e.EMP_NAME},{e.EMP_EMAIL}\""))
                        });

Test Function is as below:

static void PostResSql()
    {
        DataTable TB_M_EMPLOYEES = new DataTable();

        TB_M_EMPLOYEES.Columns.Add("EMP_ID");
        TB_M_EMPLOYEES.Columns.Add("EMP_CODE");
        TB_M_EMPLOYEES.Columns.Add("EMP_NAME");
        TB_M_EMPLOYEES.Columns.Add("EMP_EMAIL");

        DataTable TB_M_GROUP_EMP = new DataTable();
        TB_M_GROUP_EMP.Columns.Add("Id");
        TB_M_GROUP_EMP.Columns.Add("GROUP_ID");
        TB_M_GROUP_EMP.Columns.Add("EMP_ID");

        DataRow row = TB_M_EMPLOYEES.NewRow();
        row[0] = "1";
        row[1] = "E0012";
        row[2] = "Ali";
        row[3] = "@ali";
        TB_M_EMPLOYEES.Rows.Add(row);

        row = TB_M_EMPLOYEES.NewRow();
        row[0] = "2";
        row[1] = "E0013";
        row[2] = "AL";
        row[3] = "@al";
        TB_M_EMPLOYEES.Rows.Add(row);

        row = TB_M_EMPLOYEES.NewRow();
        row[0] = "3";
        row[1] = "E0014";
        row[2] = "Abi";
        row[3] = "@abi";
        TB_M_EMPLOYEES.Rows.Add(row);

        row = TB_M_EMPLOYEES.NewRow();
        row[0] = "4";
        row[1] = "E0015";
        row[2] = "Ad";
        row[3] = "@ad";
        TB_M_EMPLOYEES.Rows.Add(row);

        row = TB_M_EMPLOYEES.NewRow();
        row[0] = "5";
        row[1] = "E0016";
        row[2] = "Ea";
        row[3] = "@ea";
        TB_M_EMPLOYEES.Rows.Add(row);


        row = TB_M_GROUP_EMP.NewRow();
        row[0] = "1";
        row[1] = "1";
        row[2] = "1";
        TB_M_GROUP_EMP.Rows.Add(row);

        row = TB_M_GROUP_EMP.NewRow();
        row[0] = "2";
        row[1] = "1";
        row[2] = "2";
        TB_M_GROUP_EMP.Rows.Add(row);

        row = TB_M_GROUP_EMP.NewRow();
        row[0] = "3";
        row[1] = "1";
        row[2] = "3";
        TB_M_GROUP_EMP.Rows.Add(row);

        row = TB_M_GROUP_EMP.NewRow();
        row[0] = "4";
        row[1] = "1";
        row[2] = "4";
        TB_M_GROUP_EMP.Rows.Add(row);

        row = TB_M_GROUP_EMP.NewRow();
        row[0] = "5";
        row[1] = "1";
        row[2] = "5";
        TB_M_GROUP_EMP.Rows.Add(row);


        var result = (from empRow in TB_M_EMPLOYEES.AsEnumerable()
                      join grpRow in TB_M_GROUP_EMP.AsEnumerable()
                      on empRow.Field<string>("EMP_ID") equals grpRow.Field<string>("EMP_ID")
                      select new
                      {
                          EMP_ID = empRow.Field<string>("EMP_ID"),
                          EMP_CODE = empRow.Field<string>("EMP_CODE"),
                          EMP_NAME = empRow.Field<string>("EMP_NAME"),
                          EMP_EMAIL = empRow.Field<string>("EMP_EMAIL"),
                          GROUP_ID = grpRow.Field<string>("GROUP_ID")
                      }).GroupBy(r => r.GROUP_ID)
                        .Select(rs => new
                        {
                            GroupId = rs.Key,
                            FinalNames = string.Join(",", rs
                                            .Select(e => $"\"{e.EMP_CODE},{e.EMP_NAME},{e.EMP_EMAIL}\""))
                        });
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM