当事先不知道有多少列时,在 Linq-to-SQL 查询中加入多列

Join multiple columns in a Linq-to-SQL query when not knowing how many columns there are beforehand

假设我有以下 table 名为 TableSomeWords:

然后另一个 table 叫 SomePerson(这是主要的 table)

我要实现的是下面的结果(所以所有的世界组合起来形成一个句子):

唯一的问题是无法预先知道 TableSomeWords 中会有多少个单词。这是我目前拥有的:

var storedProcedure =
  from hdr in SomePerson
  join cl in TableSomeWords on hdr.No_ equals cl.No_ 
  group new { hdr, cl } by new { hdr.No_ } into tcl
  let firstgroupby = tcl.FirstOrDefault()
  let hdr = firstgroupby.hdr
  let cl = firstgroupby.cl
  join wml in lManLine on new { X1 = hdr.Document_Type, X2 = hdr.Business_Type, X3 = hdr.No_ } equals new { X1 = wml.Document_Type, X2 = wml.Business_Type, X3 = wml.Document_No_ }
  join v in lVendor on wml.Carrier_No_ equals v.No_
  where
  wml.Service_Type == 3 &&
  wml.Location_Code == locationCode &&
  (
    (hdr.Document_Type == 1 && hdr.Task_Date < DateTime.Now.AddYears(-100)) ||
    (new int[] { 1, 5 }.Contains(hdr.Document_Type) && (hdr.Task_Date.Date >= fromDate.Date && hdr.Task_Date < fromDate.AddDays(7)))
  )
  select new 
  {
    //ID = ...
    //Code = ...
    //Name = ...
    Words= string.Join(" ", TableSomeWords.Where(x => x.No_ == hdr.No_ &&  x.Code == "CompanyX").OrderBy(x => x.No_).ThenBy(x => x.Line_No_).GroupBy(t => t.No_).ToList()),
  }

PS:我的代码不起作用,但至少它解释了我的目标。我也不能将最后一个 .Where 放在上面的 where 子句中,因为那将 return 我只有 code = CompanyX 的行,但我希望显示所有人。

编辑: 基本上,CompanyX (x.Code) 是每个单词都有的代码。所以基本上我有很多单词和很多代码,但我只想组合代码为 CompanyX 的单词。另一个像 C001 这样的代码是另一个我可以用 (hdr.No_)

分组的代码

查看下面的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ConsoleApplication132
{
    class Program
    {
        static void Main(string[] args)
        {
            DataTable tableSomeWords = new DataTable();
            tableSomeWords.Columns.Add("id", typeof(int));
            tableSomeWords.Columns.Add("code", typeof(string));
            tableSomeWords.Columns.Add("lineNr", typeof(int));
            tableSomeWords.Columns.Add("words", typeof(string));

            tableSomeWords.Rows.Add(new object[] { 1, "C001", 1, "Foo" });
            tableSomeWords.Rows.Add(new object[] { 2, "C001", 2, "Bar" });
            tableSomeWords.Rows.Add(new object[] { 3, "C002", 1, "Hello" });
            tableSomeWords.Rows.Add(new object[] { 4, "C002", 2, "Big Blue" });
            tableSomeWords.Rows.Add(new object[] { 5, "C002", 3, "World" });


            DataTable somePerson = new DataTable();
            somePerson.Columns.Add("id", typeof(int));
            somePerson.Columns.Add("code", typeof(string));
            somePerson.Columns.Add("name", typeof(string));

            somePerson.Rows.Add(new object[] { 1, "C002", "John"});
            somePerson.Rows.Add(new object[] { 2, "C001", "Sam" });

            var results = (from person in somePerson.AsEnumerable()
                           join words in tableSomeWords.AsEnumerable() on person.Field<string>("code") equals words.Field<string>("code")
                           select new { words = words, person = person })
                           .GroupBy(x => x.person.Field<string>("code"))
                           .ToList();


            DataTable tableCombineWords = new DataTable();
            tableCombineWords.Columns.Add("id", typeof(int));
            tableCombineWords.Columns.Add("code", typeof(string));
            tableCombineWords.Columns.Add("name", typeof(string));
            tableCombineWords.Columns.Add("words", typeof(string));

            foreach (var result in results)
            {
                tableCombineWords.Rows.Add(new object[] {
                    result.FirstOrDefault().person.Field<int>("id"),
                    result.FirstOrDefault().person.Field<string>("code"),
                    result.FirstOrDefault().person.Field<string>("name"),
                    string.Join(" ",result.Select(x => x.words.Field<string>("words")))
                });
            }

        }
    }


}

您需要使用的是 LINQ GroupJoin 运算符 - 这会创建一组来自联接的所有匹配记录。使用查询语法,

var ans = from p in SomePerson
          join w in TableSomeWords on p.Code equals w.code into wj
          select new {
            p.Id,
            p.Code,
            p.Name,
            words = String.Join(" ", wj.Select(w => w.words))
          };

使用Fluent/lambda语法,

var ans2 = SomePerson.GroupJoin(TableSomeWords, p => p.Code, w => w.code,
                                (p, wj) => new { p.Id, p.Code, p.Name, words = String.Join(" ", wj.Select(w => w.words)) });