Не совсем программирование, но я терпеть не могу только макеты css только ради этого. Это контрпродуктивно, расстраивает и делает обслуживание кошмаром поплавков и наценок, когда изменение позиции одного элемента может вывести из строя всю страницу.
Это определенно не популярное мнение, но я сделал с моим расположением таблицы за 20 минут, в то время как гуру CSS тратят часы, настраивая высоту строки, поля, отступы и плавания, просто чтобы сделать что-то основное, как вертикальное центрирование абзаца.
См. Также : h undo-redo
, где перечислены все команды и их использование.
Есть два способа обойти дерево отмены. Один - вернуться «в прошлое». g +
и g-
будут проходить все узлы в дереве в хронологическом или обратном хронологическом порядке (что может немного сбивать с толку, поскольку может произвольно перемещаться между ветвями отмены, но если вы будете делать g-
достаточно долго, вы всегда доберетесь туда, куда вам нужно идти). : ранее
и : позже
принимают дескриптор времени, например 7m
или 1h
; опять же, это может произвольно перемещаться между ветвями отмены.
Другой способ - перейти к определенным узлам в дереве, используя : undo n
, где n
- это номер действия. (Все действия, т.е. добавления, удаления, замены текста нумеруются последовательно по мере их выполнения.) Вы можете посмотреть количество действий на листьях дерева отмены с помощью : undolist
. Это позволит вам легко перепрыгивать между ветками. Затем вы можете использовать u
и Ctrl-R
для перемещения вверх и вниз по этой ветви.
В справке Vim есть несколько хороших примеров. Лучший способ понять, как это работает, - немного поиграть с этим.
Дайте мне знать, если вам повезет.
Вот еще одно предложение, которое может позволить вам использовать LINQ to Entities для всего этого.
(t.TargetDate.Days - firstDay.Days) / 7
Это просто расширяет операцию так, чтобы только Выполняется целочисленное вычитание, а не вычитание DateTime
.
В настоящее время он не протестирован, поэтому может работать, а может и не работать ...
Ну, может потребоваться больше работы в зависимости от того, как индексируется БД, но вы можете просто отсортировать по дням, а затем выполнить сопоставление день -> неделя на стороне клиента.
Вы можете попробовать метод расширения для выполнения преобразования:
static int WeekNumber( this DateTime dateTime, DateTime firstDay) {
return (dateTime - firstDay).Days / 7;
}
Тогда у вас будет:
DateTime firstDay = GetFirstDayOfFirstWeekOfYear();
var userTimes = from t in context.TrackedTimes
group t by new {t.User.UserName, t.TargetDate.WeekNumber( firstDay)} into ut
select new
{
UserName = ut.Key.UserName,
WeekNumber = ut.Key.WeekNumber,
Minutes = ut.Sum(t => t.Minutes)
};
Здесь - это список методов, поддерживаемых LINQ to Entities.
Единственный вариант, который я вижу, - это получить номер недели из DateTime.Month и DateTime.Day. Примерно так:
int yearToQueryIn = ...;
int firstWeekAdjustment = (int)GetDayOfWeekOfFirstDayOfFirstWeekOfYear(yearToQueryIn);
from t in ...
where t.TargetDate.Year == yearToQueryIn
let month = t.TargetDate.Month
let precedingMonthsLength =
month == 1 ? 0 :
month == 2 ? 31 :
month == 3 ? 31+28 :
month == 4 ? 31+28+31 :
...
let dayOfYear = precedingMonthsLength + t.TargetDate.Day
let week = (dayOfYear + firstWeekAdjustment) / 7
group by ...
Я не использую Linq to Entities, но если он поддерживает .Year,. (Это может потребоваться изменить в зависимости от того, в какой день начинается ваша неделя.)
Proviso. Это формула, которую я никогда не использовал «по-настоящему». Я ввел вручную (не помню, но, возможно, скопировал это из книги), что означает, что, хотя я утроил проверку, у меня были правильные скобки, возможно, источник был неправильным. Итак, вам необходимо убедиться, что он работает перед использованием.
Лично я бы предпочел возвращать семикратный объем данных и фильтровать локально, а не использовать что-то подобное (что, возможно, объясняет, почему я никогда не пользовался форумла)
У меня была именно эта проблема в моем приложении для учета рабочего времени, которое должно сообщать о задачах по неделям. Я пробовал использовать арифметический подход, но ничего разумного не получилось. В итоге я просто добавил в базу данных новый столбец с номером недели и вычислил его для каждой новой строки. Внезапно вся боль прошла. Я ненавидел это делать, поскольку я очень верю в DRY , но мне нужно было добиться прогресса. Не тот ответ, который вам нужен, а точка зрения другого пользователя. Я буду смотреть это, чтобы получить достойный ответ.
Хорошо, это возможно, но это огромный PITA, и он обходит LINQ - часть Entity Framework. Потребовалось некоторое исследование, но вы можете выполнить то, что хотите, с помощью специфической для поставщика функции SqlServer SqlServer.DateDiff () и "Entity SQL". Это означает, что вы вернулись к строковым запросам и вручную заполняете настраиваемые объекты, но он делает то, что вы хотите. Возможно, вам удастся немного уточнить это, используя Select вместо цикла foreach и тому подобное, но я действительно заставил это работать с созданным дизайнером набором сущностей YourEntities.
void getTimes()
{
YourEntities context = new YourEntities();
DateTime firstDay = GetFirstDayOfFirstWeekOfYear();
var weeks = context.CreateQuery<System.Data.Common.DbDataRecord>(
"SELECT t.User.UserName, SqlServer.DateDiff('DAY', @beginDate, t.TargetDate)/7 AS WeekNumber " +
"FROM YourEntities.TrackedTimes AS t " +
"GROUP BY SqlServer.DateDiff('DAY', @beginDate, t.TargetDate)/7, t.User.UserName", new System.Data.Objects.ObjectParameter("beginDate", firstDay));
List<customTimes> times = new List<customTimes>();
foreach (System.Data.Common.DbDataRecord rec in weeks)
{
customTimes time = new customTimes()
{
UserName = rec.GetString(0),
WeekNumber = rec.GetInt32(1)
};
times.Add(time);
}
}
class customTimes
{
public string UserName{ get; set; }
public int WeekNumber { get; set; }
}
учитывается ли лямбда? Я начал с синтаксиса linq, но, кажется, думаю о лямбда-выражениях C # 3.0, когда дело доходит до декларативного программирования.
public static void TEST()
{
// creating list of some random dates
Random rnd = new Random();
List<DateTime> lstDte = new List<DateTime>();
while (lstDte.Count < 100)
{
lstDte.Add(DateTime.Now.AddDays((int)(Math.Round((rnd.NextDouble() - 0.5) * 100))));
}
// grouping
var weeksgrouped = lstDte.GroupBy(x => (DateTime.MaxValue - x).Days / 7);
}
Странно, что никто еще не опубликовал метод GetWeekOfYear платформы .NET Framework.
просто сделайте свой первый выбор, добавьте фиктивное свойство weeknumber, затем переберите их все и используйте этот метод для установите правильный номер недели для вашего типа, он должен быть достаточно быстрым, чтобы выполнить один цикл между двумя выборками, не так ли?:
public static int GetISOWeek(DateTime day)
{
return System.Globalization.CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(day, System.Globalization.CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
}
Я думаю, что единственная проблема, с которой вы столкнулись, - это арифметические операции с типом DateTime, попробуйте следующий пример. Он сохраняет операцию в БД как скалярную функцию, возвращает только желаемые сгруппированные результаты. Функция .Days не будет работать с вашей стороны, потому что реализация TimeSpan ограничена и (в основном) доступна только в SQL 2008 и .Net 3.5 SP1, дополнительные примечания здесь по этому .
var userTimes = from t in context.TrackedTimes
group t by new
{
t.User.UserName,
WeekNumber = context.WeekOfYear(t.TargetDate)
} into ut
select new
{
UserName = ut.Key.UserName,
WeekNumber = ut.Key.WeekNumber,
Minutes = ut.Sum(t => t.Minutes)
};
Функция в базе данных добавлено в ваш контекст (как context.WeekOfYear):
CREATE FUNCTION WeekOfYear(@Date DateTime) RETURNS Int AS
BEGIN
RETURN (CAST(DATEPART(wk, @Date) AS INT))
END
Для дополнительной информации: Вот поддерживаемые методы DateTime, которые правильно транслируются в сценарии LINQ to SQL
Вы можете попробовать сгруппироваться по годам и неделямNumber, получив его в собственность DayOfYear
var userTimes = from t in context.TrackedTimes
group t by new {t.User.UserName, Year = t.TargetDate.Year, WeekNumber = t.TargetDate.DayOfYear/7} into ut
select new
{
UserName = ut.Key.UserName,
WeekNumber = ut.Key.WeekNumber,
Minutes = ut.Sum(t => t.Minutes)
};