Как стать автором
Обновить

Комментарии 13

Как я понял из статьи за основу вы взяли код MiniProfiler. Тогда прежде чем решать вопрос монетизации, следует почитать лицензию на MiniProfiler. Возможно что кроме OpenSource у вас не останется вариантов.
Совершенно верно, за основу был взят код от MiniProfiler.
Проект опубликован под Apache лицензией. Насколько я понял, с некоторыми оговорками лицензия разрешает использование кода в платных продуктах.
SQL Server Profiler — не то, чтобы сильно не удобный… он просто не для EF
Он рассчитан на просмотр того, что происходит на SQL Server, а не того, что выходит с EF.

Лично меня больше всего в sql server profile досаждало- необходимость иметь права, куда большие чем нужные приложению.
Т.е. под стандартной учеткой на чтение данных использование профилировщика- не получится.
Есть еще кстати одно решение, если вы дебажитесь из студии- Intellitrace можно включить настройку логировать события ado.net.
Оно конечно не подходит не для .net проектов, но EF я именно так дебажил, когда не хватало прав на сервере.
В стандартном SQL-профайлере есть очнь важная вещь, которой здесь нет — оценка трудоемкости выполнения запроса в терминах CPU/disk/IO cost — это гораздо важнее, чем время выполнения, которое в однопользовательском режиме с тестовыми данными практически ни о чем не говорит. Вернее, как — все, что выполняется больше, чем за период тика системного таймера при разработке — скорее всего будет приносить проблемы с производительностью в продакшене.

С другой стороны, польза тула несомненно есть — хотя бы для того, чтобы показать, чего стоит на стороне бакенда «легкость» манипулирования данными средствами EF
Вы правы, но на мой взгляд, использование EF в проектах для которых нагрузка имеет критическое значение, не самая удачная идея.
По разделу «Немного юмора», было бы интересно узнать: как пацан к успеху шёл? Это EF4?
EF6.
Ужаснитесь)
CompanyEmployees
	using (var ctx = new CompanyEmployees())
	{
		int minYear = ctx.OccupationHistories.Min(o => o.StartDate.Year);
		int maxYear = ctx.OccupationHistories.Max(o => o.EndDate.HasValue ? o.EndDate.Value.Year : DateTime.Now.Year);

		List<int> yearsList = Enumerable.Range(minYear, maxYear - minYear + 1).ToList();
		List<int> monthList = Enumerable.Range(1, 12).ToList();

		var qry1 = from y in yearsList
				   from m in monthList
				   select new DateTime(y, m, 1);
		var firstDays = qry1.ToList();

		var qry2 = from y in yearsList
				   from m in monthList
				   select new DateTime(y, m, DateTime.DaysInMonth(y, m));
		var lastDays = qry2.ToList();

		var qry = from s in
					  (
						  from o in ctx.OccupationHistories
						  join d in ctx.Divisions
							  on o.DivisionID equals d.Id
						  join p in ctx.Positions
							  on o.PositionID equals p.Id
						  from x in
							  (
								  from a in firstDays
								  join b in lastDays
									  on new { a.Year, a.Month } equals new { b.Year, b.Month }
								  select new
								  {
									  FirstDay = a,
									  LastDay = b
								  })
						  where DateTime.Compare(o.StartDate, x.LastDay) <= 0 &&
						  DateTime.Compare(o.EndDate.HasValue ? o.EndDate.Value : DateTime.Now, x.FirstDay) >= 0

						  orderby o.EmployeeID
						  select new
						  {
							  EmployeeId = o.EmployeeID,
							  Division = d.Name,
							  Position = p.Name,
							  Year = x.FirstDay.Year,
							  Month = x.LastDay.Month
						  })
				  group s by new { s.Division, s.Position, s.Year, s.Month } into g
				  orderby g.Key.Year, g.Key.Month, g.Key.Division, g.Key.Position
				  select new EmployeesCount
				  {
					  Division= g.Key.Division,
					  Position= g.Key.Position,
					  Year= g.Key.Year,
					  Month= g.Key.Month,
					  EmployeeCount = g.Count()
				  };

		return qry.ToList();

Кошмар. Средствами SQL — два подзапроса или временных таблицы-генератора для месяца и диапазона лет, подзапрос с cross join с ними внутри, дальше inner join с occupation histories по datepart(year… и datepart(month… и затем count / group by — как-то так
Спасибо, искал в свое время что-то более удобное стандартного SQL профайлера, но все таки мой инструмент служит несколько для другого.
Очень странный и я бы даже сказал опасный пример с LogFormatter: инстанс интерцептора регистрируется один раз и используется изо всех тредов; в реальных условиях (например в каком-нть сайте с десятками одновременных реквестов) логика start / stop stopwatch-ей просто не работает — любая из команд начинает таймер, любая из других стопает таймер, да и вообще несколько тредов могут одновременно читать и писать в переменную таймера. Можно пытаться развлекаться с ThreadStatic на переменной, но это тоже не сработает в случае асинхронных запросов в EF.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории