Нужна помощь с логикой C # - PullRequest
0 голосов
/ 31 августа 2010

У меня есть таблица с полями ниже,

table Shows,
  Id   Name   Time
   1     A    7/28/2010 11:15:00 AM
   2     B    7/29/2010 8:50:00 AM
   3     C    7/29/2010 8:55:00 AM

У меня есть объект Show, в котором есть данные из всех полей. Теперь я хочу иметь пользовательский интерфейс, который показывает количество показов на почасовой основе за все дни.

Date 7/28/2010
  Hours Count
  11-12   1

Date 7/29/2010
  Hours Count
  8-9   2

Я понятия не имею, как мне это сделать в C # (логика для этого.) Кроме того, есть ли что-то вроде функции разнесения, которую мы имеем в php, в C #. Потому что моя база данных имеет значение 29.07.2010 8:55:00 и я хочу перебить дату и время. Кто-нибудь может помочь с логикой для создания вышеупомянутого интерфейса?

Поскольку я хочу отображать все часы и их количество для каждой даты, придется ли мне использовать список для дат и в этом другом списке со всеми часами и счетами на эту дату? Можете ли вы показать мне, как это сделать?

Ответы [ 4 ]

4 голосов
/ 31 августа 2010

Предполагая, что вы можете использовать LINQ, вы можете довольно легко выполнить всю группировку и упорядочение в C #. (Я предполагаю, что это просто список объектов DateTime, а не полных объектов Show. Похоже, вы можете получить DateTime для каждого Show с помощью простого оператора LINQ Select.)

var shows = new[]
            {
                new DateTime(2010, 7, 28, 11, 15, 0),
                new DateTime(2010, 7, 29, 8, 50, 0),
                new DateTime(2010, 7, 29, 8, 55, 0)
            };

var dates = shows.GroupBy(d => d.Date).OrderBy(d => d.Key);
foreach (var date in dates)
{
    Console.WriteLine("Date {0}", date.Key.ToShortDateString());
    var hours = date.GroupBy(d => d.Hour).OrderBy(d => d.Key);
    Console.WriteLine("\tHours\tCount");
    foreach (var hour in hours)
        Console.WriteLine("\t{0}-{1}\t{2}", hour.Key, (hour.Key+1)%24, hour.Count());
}

Это обеспечивает вывод:

Date 7/28/2010
        Hours   Count
        11-12   1
Date 7/29/2010
        Hours   Count
        8-9     2

Обратите внимание, что это простой пример консольного приложения. Вы не указали, какую технологию графического интерфейса вы используете (WinForms, WPF), поэтому я оставлю это в качестве упражнения, чтобы взять результаты группировки и применить их в графическом интерфейсе.

Редактировать: вот пример формата в XAML с использованием вложенных ItemsControls с привязкой DataBinding к оператору LINQ.

<ItemsControl Name="ShowDates" ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
    <DataTemplate>
        <HeaderedContentControl HeaderStringFormat="Date: {0}">
            <HeaderedContentControl.Header>
                <StackPanel>
                    <TextBlock Text="{Binding Path=DateString, StringFormat='Date: {0}'}" />
                    <TextBlock Margin="20,1,1,1" Text="Hour : Shows"/>
                </StackPanel>
            </HeaderedContentControl.Header>
            <ItemsControl Name="HoursList" Margin="20,1,1,1" ItemsSource="{Binding Path=Hours}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <TextBlock>
                            <TextBlock.Text>
                                <MultiBinding StringFormat="{}{0}-{1} : {2}">
                                    <MultiBinding.Bindings>
                                        <Binding Path="HourStart" /> 
                                        <Binding Path="HourEnd" /> 
                                        <Binding Path="Count" /> 
                                    </MultiBinding.Bindings>
                                </MultiBinding>
                            </TextBlock.Text>
                        </TextBlock>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </HeaderedContentControl>
    </DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

При этом используется измененная версия моего исходного оператора LINQ, чтобы упростить подключение DataBinding. Этот код находится в конструкторе моего тестового окна.

    var result =
    shows
    .GroupBy(d => d.Date)
    .Select(gp => new{
        Date = gp.Key,
        DateString = gp.Key.ToShortDateString(),
        Hours = gp.GroupBy(d => d.Hour)
                    .Select(hgp => new {
                        HourStart = hgp.Key,
                        HourEnd = (hgp.Key + 1) % 24,
                        Count = hgp.Count()
                    })
                    .OrderBy(h => h.HourStart)
    });
ShowDates.DataContext = result;
3 голосов
/ 31 августа 2010

Большинство баз данных имеет возможности преобразования.Как и SQL Server, например, вы можете преобразовать дату и отформатировать ее, чтобы она отображалась как 29.07.2010 в ключевом слове конвертации.Кроме того, вы можете использовать функцию datepart в SQL для извлечения первого часа (вам нужно рассчитать второй час, добавив один, если час не равен 12, а затем вернуть 1, что можно сделать с помощью функции).

Итак, сгруппируйте по дате, затем по диапазону часов, а затем посчитайте количество вхождений ... это логика.

HTH.

2 голосов
/ 31 августа 2010

Что касается вашей проблемы DateTime, так как 7/29/2010 8:55:00 AM является действительным DateTime, вы можете просто использовать parse

System.DateTime dateTime;
System.DateTime.TryParse("7/29/2010 8:55:00 AM", out dateTime);
var date = dateTime.Date;
var time = dateTime.TimeOfDay;

Доступны различные другие свойства и методы. Если вы просто хотите строки, вы можете использовать

var timeString = dateTime.ToString("hh:mm");

В C # вам действительно редко нужно манипулировать строками, если вы используете «нормальные» типы данных, такие как даты, числа, время и т. Д.

0 голосов
/ 31 августа 2010

Ваш оператор SQL может быть использован для разбиения ваших данных на группы.Например, вот оператор SQL, который я бы использовал (странный разбор, который вы видите в первом столбце, - это просто мой способ отбросить время из объекта datetime):

SELECT 
  CONVERT(DATETIME, FLOOR(CONVERT(FLOAT, DateTimeColumnName))) as [Date],
  DATEPART(Hour, DateTimeColumnName) as [Hour], 
  Count(*) as [Count]
FROM Shows
GROUP BY 
  FLOOR(CONVERT(FLOAT, DateTimeColumnName)), 
  DATEPART(Hour, DateTimeColumnName)

Это вернет вам набор данных, которыйсодержит дату, час и количество записей, соответствующих этим критериям.Что-то вроде:

[Date]               [Hour]       [Count]
7/28/2010 00:00:00   11           1
7/29/2010 00:00:00   8            2

Просто возьмите эти данные и отформатируйте их так, как вы хотите в своем пользовательском интерфейсе.

Что касается вашего другого вопроса, объект DateTime содержит свойства для различных частей времени, поэтому просто приведите ваши данные datetime в объект DateTime, как предложил Чад.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...