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

时间:2019-09-24 15:12:45

标签: c# linq-to-sql

假设我有一个名为TableSomeWords的下表:

enter image description here

然后是另一个名为SomePerson的表(这是主表)

enter image description here

我想要实现的是以下结果(因此所有世界结合在一起就构成了一个句子):

enter image description here

唯一的问题是,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,因为那只会返回代码= CompanyX但我希望所有人显示的行。

编辑: 基本上,CompanyX(x.Code)是每个单词都有的代码。因此,基本上,我有很多带有很多代码的单词,但是我只想合并具有代码CompanyX的单词。而其他代码(例如C001)是我可以用(hdr.No_)分组的另一个代码

2 个答案:

答案 0 :(得分:1)

请参见下面的代码:

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")))
                });
            }

        }
    }


}

答案 1 :(得分:0)

您需要使用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)) });