Получить значение DataTable из соседней ячейки без цикла ForEach?
Я работаю над решением этой проблемы: создать несколько результатов из одной строки, объединяющей две или три таблицы на основе условных результатов таблицы table1? и пока я хотел бы взять Strawberry's
Совет, я не могу, поэтому я пытаюсь сейчас сделать больше в C#, а не через БД, но также пытаюсь быть умным относительно того, сколько ЦП я использую.
В масштабе, таблица1 может иметь 50000 записей, которые имеют эти 20 codetype
поля, которые должны быть оценены, прежде чем их можно будет сопоставить с таблицей 2, которая имеет около 2000 строк, или таблицей 3, которая может иметь 200 000 строк. Чтобы не забивать БД, я собираюсь хранить в памяти все, что возможно, максимально ограничивать результаты по дате, но я хочу избежать 2000 циклов foreach на 20 совпадений кодовых типов.
Для начала я получаю необходимые результаты из таблицы 2 и загружаю их в таблицу данных C#, которая хранится как переменная с именем descriptionLookup
:
id, description
13 Item 13 Description
15 Item 15 Description
17 Item 17 Description
18 Item 18 Description
21 Item 21 Description
28 Item 28 Description
45 Item 45 Description
И таблица3 как lookupTable
:
id, table2id
1 15
33 17
21 28
делаем просто (не показывая весь окружающий код, просто уместно):
var rawData = new DataTable();
using (OdbcCommand com = new OdbcCommand("SELECT id, description from table2", conn))
{
using (OdbcDataReader reader = com.ExecuteReader())
{
rawData.Load(reader);
conn.Close();
return rawData;
}
}
Затем я присвоил это переменной, которая вызвала функцию. Теперь я имею дело с таблицей 1:
codeid1,codeid2,codeid3,...codeid20 ... codetype1,codetype2,codetype3,.....codetype20
18 13 1 33 0 0 1 1
13 21 45 0 0 1 0 0
Используя строку foreach, мне нужно оценить каждый столбец codetype на 1 или 0. Когда codetype=1, мне нужно получить связанный кодовый код, а затем выполнить поиск данных, которые я храню в памяти, как descriptionLookup
чтобы увидеть, что table2id соответствует id
в lookuptable
и затем использовать это для поиска описания связанного поля в таблице2.
Если codetype равен 0, мне просто нужно соответствовать codeid
со связанным полем описания в табл.
Я смотрю на то, как это изложить, и все, о чем я могу думать, это:
DataTable descriptionLookup= DB.ExecuteQuery("SELECT id, description from table2");
DataTable lookupTable= DB.ExecuteQuery("SELECT id, table2id from table3");
DataTable mainData= DB.ExecuteQuery("SELECT * from from table1");
foreach (var row in mainData)
{
var manDataId = row.GetColumn("id");
var subroutine = new Dictionary<string, string>();
for (var index = 1; index < 20; index++)
{
string description;
if (row.GetColumn("codetype" + index) == "1")
{
int idLookup = row.GetColumn(["codeid" +index]);
foreach (var row2 in lookupTable)
{
if (row3.GetColumn("id") == idLookup)
{
descriptionId = row3.GetColumn("table2id");
foreach (var row2 in descriptionLookup)
{
if (row.GetColumn("id") == descriptionId)
{
description = row2.GetColumn("description").ToString();
}
}
}
}
}elseif (row.GetColumn("codetype" + index) == "0")
{
descriptionId = row.GetColumn(["codeid" +index]);
foreach (var row2 in descriptionLookup)
{
if (row.GetColumn("id") == descriptionId)
{
description = row2.GetColumn("description").ToString();
}
}
}
subroutine.Add(manDataId.ToString(), description.ToString());
}
ArrayData.Add(subroutine);
}
Я не пробовал запускать приведенный выше код, так что, возможно, есть проблема или две, но он помогает перебрать тысячи записей, используя foreach (var row3 in idLookup)
, В качестве альтернативы, кажется, делается запрос к БД, но это кажется более интенсивным, чем просто циклически проходить через то, что находится в памяти, но кажется, что есть лучший способ, который мне не хватает, как получить id
или же table2id
без использования foreach.
Чтобы сделать этот вопрос самым длинным в истории:) Вот мой SQL, который у меня есть:
SELECT table1.id, table1.field1, table1.field2,
table2.description, fee.amt as fee FROM table2
INNER JOIN table1
ON table2.id = table1.codeid1
OR table2.id = table1.codeid2
OR table2.id = table1.codeid3
OR table2.id = table1.codeid4
OR table2.id = table1.codeid5
OR table2.id = table1.codeid6
OR table2.id = table1.codeid7
OR table2.id = table1.codeid8
OR table2.id = table1.codeid9
OR table2.id = table1.codeid10
OR table2.id = table1.codeid11
OR table2.id = table1.codeid12
OR table2.id = table1.codeid13
OR table2.id = table1.codeid14
OR table2.id = table1.codeid15
OR table2.id = table1.codeid16
OR table2.id = table1.codeid17
OR table2.id = table1.codeid18
OR table2.id = table1.codeid19
OR table2.id = table1.codeid20
INNER JOIN fee ON table2.id = fee.id
WHERE table1.codetype1 = 0
AND table1.codetype2 = 0
AND table1.codetype3 = 0
AND table1.codetype4 = 0
AND table1.codetype5 = 0
AND table1.codetype6 = 0
AND table1.codetype7 = 0
AND table1.codetype8 = 0
AND table1.codetype9 = 0
AND table1.codetype10 = 0
AND table1.codetype11 = 0
AND table1.codetype12 = 0
AND table1.codetype13 = 0
AND table1.codetype14 = 0
AND table1.codetype15 = 0
AND table1.codetype16 = 0
AND table1.codetype17 = 0
AND table1.codetype18 = 0
AND table1.codetype19 = 0
AND table1.codetype20 = 0
Это прекрасно работает до тех пор, пока нет codetype
с 1, в противном случае эта запись будет пропущена. Скорее всего, не будет ни одного ряда, где все codeid / codetype
заполнены, и никогда не будет случая, когда codetype
будет 1 по всей доске, чтобы соответствовать обратному этому запросу.