Сборка SQL с помощью foreach - PullRequest
0 голосов
/ 16 мая 2018

У меня есть этот код:

private void button1_Click(object sender, EventArgs e)
{
    foreach(Int_String partner in partneri)
    {
        double danaBezProdaje = (DateTime.Today - Komercijalno.Partner.PoslednjaKupovina(partner._int)).TotalDays;
        if (danaBezProdaje > 31 && danaBezProdaje < 1100)
        {
            NeaktivniPartner np = new NeaktivniPartner();
            np.ppid = partner._int;
            np.naziv = partner._string;
            np.danaBezKupovine = danaBezProdaje;
            neaktivniPartneri.Add(np);
        }
    }
    dataGridView1.DataSource = M.List.ConvertToDataTable(neaktivniPartneri);
}

Итак, у меня есть List<Int_String> partneri, который содержит 5k строк. Для каждого из них я запускаю Komercijalno.Partner.PoslednjaKupovina(partner._int), который содержит инструкцию SQL, которая выглядит следующим образом:

public static DateTime PoslednjaKupovina(int ppid)        
{
    using (FbConnection con = new FbConnection(M.Baza.connectionKomercijalno2018))
    {
        con.Open();
        using (FbCommand cmd = new FbCommand("SELECT DATUM FROM DOKUMENT WHERE PPID = @PPID ORDER BY DATUM DESC", con))
        {
            cmd.Parameters.AddWithValue("@PPID", ppid);

            FbDataReader dr = cmd.ExecuteReader();

            if (dr.Read())
                return Convert.ToDateTime(dr[0]);
            else
                return new DateTime(1, 1, 1);
        }
    }
}

Таким образом, оператор SQL выполняется 5k раз, что слишком медленно.

Итак, как я могу передать свой List<Int_String> или просто массив целых чисел в команду sql, чтобы там я выполнял один раз (внутри foreach или как-нибудь еще) и возвращал dataAdapter, поэтому я выполняю SQL только один раз.

Возвращенный DataAdapter должен выглядеть следующим образом:

| ppid     | datum    |

Допустим, у меня есть таблица PARTNER (из которой я заполняю список partneri с SELECT PPID, NAZIV FROM PARTNER) со следующими данными:

| PPID    | NAZIV    |
| 1       | name001  |
| 2       | name002  |
| 3       | name003  |
| 4       | name004  |

И скажем, моя таблица DOKUMENT имеет следующие данные:

| ID      | PPID    | DATE       |
| 1       | 2       | 12.03.2018 |
| 2       | 3       | 12.03.2018 |
| 3       | 2       | 05.03.2018 |
| 4       | 2       | 03.04.2018 |
| 5       | 1       | 26.03.2018 |
| 6       | 4       | 21.02.2018 |
| 7       | 4       | 06.05.2018 |

И вывод, который я хочу:

| PPID    | DATE       |
| 1       | 26.03.2018 |
| 2       | 03.04.2018 |
| 3       | 12.03.2018 |
| 4       | 06.05.2018 |

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

Делая это как ответ, потому что под вопросом уже очень много комментариев, так что он просто потеряется в шуме.

Так как я могу передать свой список или просто массив целых в команду sql, чтобы я выполнял один раз

Этот вопрос обсуждался здесь: Фильтр sql на основе C # List вместо таблицы фильтров

В зависимости от того, насколько типичным (частым) является запрос и насколько велики данные, существует несколько способов.

  • Глобальные временные таблицы
  • Имитация ГТТ с использованием UNION ALL и нескольких select {constants} from RDB$database
  • Сведение списка в одну длинную строку специального формата и использование обратного LIKE сопоставления.

PS. Для вашей конкретной задачи ответ Марка определенно намного лучше: вам не нужно извлекать много данных с сервера только для того, чтобы передать их в другом запросе. Я просто хотел связать вопрос, связанный с частью этого, на который уже был дан ответ.

0 голосов
/ 16 мая 2018

Вы можете заменить всю свою логику одним запросом, который выполняет:

select d.ppid, max(d.datum)
from partner p
inner join dokument d
    on d.ppid = p.ppid
group by d.ppid

Возможно, вам потребуется добавить where -клаузу с дополнительными условиями, чтобы выбрать, каких партнеров вы хотите иметь.

...