asp.net несколько sqlcommands в одном GridView

У меня проблема с отображением нескольких команд sql в одном GridView. Может быть, мне не нужны две sqlcommands для отображения из двух таблиц, но я не знаю, как это сделать. Первая команда — получить всех сотрудников, у которых есть отпуск между двумя датами. Вторая команда, которую я использую для получения дат по идентификатору. Но я не знаю, как связать их обоих с одним GridView, чтобы показать как прикрепленное изображение. Заранее спасибо.

Сейчас я получаю следующее:
Альберт 16-03-2016
Альберт 17-03-2016

Альберт 18-03-2016
Джоанна 17-03-2016

Джоанна 18.03.2016
Эрик 18.03.2016

Вместо
Альберт 16-03-2016, 17-03-2016, 18-03-2016
Джоанна 17-03-2016, 18-03-2016
Эрик 18-03-2016
Я думаю, что мне нужно зацикливаться между двумя состояниями While и, возможно, с одной командой sql?
введите здесь описание изображения

Мой код:

    using (SqlConnection con = new SqlConnection(connection))
{
 con.Open();
 SqlCommand cmd = new SqlCommand(" SELECT distinct E.EmployeeId, E.FirstName  
 FROM Employee E INNER JOIN Vacation V ON E.EmployeeId = V.EmployeeId " +
  " WHERE ((V.Dates >= @Start AND V.Dates <= @End) ) ", con);
  cmd.Parameters.AddWithValue("@Start", (Calendar1.SelectedDates[0]).Date.ToShortDateString());
 cmd.Parameters.AddWithValue("@End", (Calendar1.SelectedDates[Calendar1.SelectedDates.Count - 1]).Date.ToShortDateString());
using (SqlDataReader dr = cmd.ExecuteReader())
 {
   while (dr.Read())
    {

 Response.Write((dr[1]).ToString() + "  "); // Cheack if retrivs Employeename
 // Now By Id I want to get all dates belong to specifik employee

SqlCommand cmd2 = new SqlCommand(" SELECT V.Dates FROM Vacation V " +
" WHERE ((V.Dates >= @Start AND V.Dates <= @End) ) ", con);
cmd2.Parameters.AddWithValue("@Start", (Calendar1.SelectedDates[0]).Date.ToShortDateString());
cmd2.Parameters.AddWithValue("@End", (Calendar1.SelectedDates[Calendar1.SelectedDates.Count - 1]).Date.ToShortDateString());
cmd2.Parameters.AddWithValue("@EmployeeId", Convert.ToInt32(dr[0]));                                    
using (SqlDataReader dr2 = cmd2.ExecuteReader())
{
 while (dr2.Read())
    {
    //Response.Write(Convert.ToDateTime(dr2[0]));
     GridView7.DataSource = cmd2.ExecuteReader();
GridView7.DataBind();
    }

   }
       Response.Write("<br/>");
 } 


  }
    con.close();
}
GridView7.DataSource = cmd.ExecuteReader();
GridView7.DataBind();

person Jonas Willander    schedule 15.03.2016    source источник
comment
Вам нужно обрабатывать информацию в виде столбца? почему бы не использовать все даты отпуска в одном столбце nvarchar(max) и просто добавить запятую между ними? я говорю это, потому что способ, которым вы пытаетесь достичь этого, будет беспорядком, поскольку все даты не совпадают между сотрудниками, вы можете использовать динамическую сводную таблицу SQL, но это оставит вас с кучей нулей ( или пустые) пробелы.   -  person thepanch    schedule 15.03.2016
comment
@thepanch Спасибо за ваш ответ, но мне нужно показать результат в таблице или GridView. Это возможно? Это нормально с динамической сводной таблицей SQL, даже если она оставит кучу нулевых (или пустых) пробелов. Тогда это возможно? Еще раз спасибо.   -  person Jonas Willander    schedule 15.03.2016
comment
@thepanch: мой код работает, если я использую Response.Write(.....), например: With Response.Write((dr[1]).ToString() + ); И Response.Write(Convert.ToDateTime(dr2[0])); Я могу восстановить, как хочу, но я не хочу, чтобы он писал на странице как есть. Я хочу показать их в таблице, GridView или динамической сводной таблице SQL.   -  person Jonas Willander    schedule 15.03.2016


Ответы (1)


Синтаксис FOR XML PATH позволяет вашему запросу сгруппировать несколько значений в одно:

SELECT 
    E.EmployeeId, 
    E.FirstName,
    REPLACE(STUFF((
        SELECT 
            COALESCE('¶' + V.Dates, '')
        FROM 
            Vacation V 
        WHERE 
            V.EmployeeId = E.EmployeeId AND V.Dates >= @Start AND V.Dates <= @End
        FOR XML PATH('')), 1, 1, ''), '¶', ', ') AS VacationDates
FROM 
    Employee E

Вы можете заменить разделитель ', ' чем-то другим, если хотите.

Примечание: извините за многократные правки. Я просто не уверен, как вы связываете сотрудников, отпуск и даты. Этот фрагмент кода в основном показывает идею синтаксиса FOR XML PATH.

person ConnorsFan    schedule 15.03.2016
comment
Спасибо за ваши ответы, я получил ошибку. Необходимо объявить скалярную переменную @Start, но я объявляю ее как cmd2.Parameters.AddWithValue(@Start, (Calendar1.SelectedDates[0]).Date.ToShortDateString()); - person Jonas Willander; 15.03.2016
comment
Вы получаете эту ошибку при вставке этого запроса в свой код или при его тестировании непосредственно в базе данных? - person ConnorsFan; 15.03.2016
comment
Это нормально, но мой код работает, если я использую Response.Write(.....), например: With Response.Write((dr[1]).ToString() + ); И Response.Write(Convert.ToDateTime(dr2[0])); Я могу восстановить, как хочу, но я не хочу, чтобы он писал на странице как есть. Я хочу показать их в таблице, GridView или динамической сводной таблице SQL. - person Jonas Willander; 15.03.2016
comment
Когда я вставил свой код, но он ответил мне, что он думал, что я запустил путь XML или что-то в этом роде, поэтому его код не будет работать. На самом деле мой код как есть, он работает, но, как я уже сказал, прежде чем я хочу, я хочу показать их в таблице, GridView или динамической сводной таблице SQL. Но я думаю, что должен использовать то же имя sqlcommand. Я использую две команды sql, потому что мне нужно сначала получить идентификатор сотрудника. Если вы изучите мой код... то как я могу использовать одну команду вместо двух sqlcommand и двух ExecuteReader()? Думаю, проблема в том, что я использую две команды и ExecuteReader(). Спасибо за ваше время - person Jonas Willander; 15.03.2016
comment
Мой ответ - способ сделать это только с одним запросом. Я не знаю, какое именно сообщение об ошибке вы получаете. Обычно я сохраняю свой запрос как хранимую процедуру и вызываю процедуру из кода. Вы можете сначала протестировать мой запрос в базе данных (указав некоторые значения для начала и конца) и посмотреть, соответствует ли результат тому, что вы хотите. Если это так, то мы можем увидеть, как заставить его работать в вашем коде. - person ConnorsFan; 16.03.2016
comment
Извини, я думал, что ты был другим парнем thepanch. Я был сбит с толку. Извини. Я попробовал ваш код letest и прямо в SQL Managment Studio возвращает все NULL VacationDates, но в базе данных есть даты. И когда я попытался вставить в свой код, он говорит, что преобразование не удалось при преобразовании даты и/или времени из строки символов - person Jonas Willander; 16.03.2016
comment
Поле VacationDates будет выведено в виде строки символов. Таким образом, вы не можете преобразовать его в дату. Для данного сотрудника это должно выглядеть так: 2016-03-18, 2016-03-17, 2016-03-16. Что касается того, почему этот столбец данных пуст... Я вижу, что он будет пустым для некоторых сотрудников (это можно легко исправить), но я думал, что для других будут данные. Я предполагаю, что вы дали соответствующие значения @Start и @End, когда пробовали это... О, я только что удалил лишнее WHERE в запросе; вы видели это в своем тесте? - person ConnorsFan; 16.03.2016
comment
Да, я удалил лишнее WHERE с самого начала. Вместо начала я написал 2016-0315 и конец 2016-03-20 и по-прежнему давал мне NULL для всех сотрудников (около 10 сотрудников) даже для тех, кто работает, когда я пытался напрямую в SQL-сервере управления. Это идеально, чтобы показать мне даже для тех, кто работает. Я хочу видеть всех сотрудников, но рядом с ними даты для тех, кто находится в отпуске между началом и концом. - person Jonas Willander; 16.03.2016
comment
Давайте продолжим обсуждение в чате. - person Jonas Willander; 16.03.2016