Объединяйте несколько столбцов в запросе Linq-to-SQL, не зная заранее, сколько столбцов существует - PullRequest
0 голосов
/ 24 сентября 2019

Допустим, у меня есть следующая таблица с именем 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, потому что это вернет мои единственные строки, где code = CompanyX, но я хочу, чтобы все люди были показаны.

EDIT: в основном CompanyX (x.Code) - это код каждого слова.Так что в основном у меня много слов со многими кодами, но я хочу только объединить слова, которые имеют код CompanyX.А другой код, такой как C001, - это другой код, по которому я могу просто сгруппировать (hdr.No_)

Ответы [ 2 ]

1 голос
/ 24 сентября 2019

См. Код ниже:

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

        }
    }


}
0 голосов
/ 25 сентября 2019

Вам нужно использовать оператор 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)) });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...