суббота, 29 августа 2009 г.

Silverlight: SketchFlow для прототипирования интерфейсов

Очень интересная статья с примером использования SketchFlow для создания прототипов приложения. И перевод на русский Владимира Юнева.

пятница, 28 августа 2009 г.

ASP.NET MVC: DropDownList

При редактировании некоторых полей объекта очень часто необходимо использование контрола DropDownList. А чтоб его заполнить данными нужен объект типа IEnumerable.

Для примера понадобятся слудующие сущности EmployeeEntity, JobEntity

public class EmployeeEntity
  {
    public virtual int EmployeeId { get; set;}
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
    public virtual String JobId { get; set; }
  }


* This source code was highlighted with Source Code Highlighter.


public class JobEntity
  {
    public virtual string JobId { get; set; }
    public virtual string JobTitle { get; set; }
  }


* This source code was highlighted with Source Code Highlighter.


Что бы удобно передать во View модель данных содержащую как экземпляр Employee так и список Job`ов создаем класс обертку:
public class EmployeeEditViewData
  {
    public EmployeeEntity Employee;
    public IEnumerable<SelectListItem> Jobs;
  }


* This source code was highlighted with Source Code Highlighter.


Теперь необходимо создать Action для Employee контроллера
  1. public ActionResult Edit(int id)
  2.     {
  3.       EmployeeEntity employeeEntity = _employeeRepository.EditById(id);
  4.       IEnumerable<SelectListItem> jobs =
  5.         Domain
  6.         .CurrentSession
  7.         .CreateCriteria<Job>()
  8.         .List<Job>()
  9.         .Select(j => new SelectListItem
  10.                  {
  11.                    Text = j.JobTitle,
  12.                    Value = j.JobId,
  13.                    Selected = employeeEntity.JobId == j.JobId
  14.                  });
  15.  
  16.       EmployeeEditViewData viewData = new EmployeeEditViewData
  17.                         {
  18.                           Employee = employeeEntity,
  19.                           Jobs = jobs
  20.                         };
  21.       return View("Edit", viewData);
  22.     }
* This source code was highlighted with Source Code Highlighter.

А теперь по порядку:
строка 3 - получение экземляра объекта EmployeeEntity;
строки 4-14 - получение экземляра IEnumerable Jobs;
строки 16-20 - создаем EmployeeEditViewData и инициализируем поля ранее получеными объектами;

Для данного action необходимо создать строго типизированную view на основе класса EmployeeEditViewData. У меня студийный генератор не смог сгенерить заготовку view для редактирования полей, но ничего не мешает это сделать самому.
Для поля в котором нам понадобится DropDownList пишем следующий код:
    <p>
      <label for="JobId">
        Job:</label>     
      <%= Html.DropDownList("JobId",Model.Jobs) %>      
    </p>


* This source code was highlighted with Source Code Highlighter.


В общем то все.

четверг, 20 августа 2009 г.

ASP.NET + NHibernate + Oracle и Pagination

Постраничный вывод в ASP.NET + NHibernate + Oracle.
Выдергивать из базы данные постранично желание отнюдь не запретное, посему решено было его удовлетворить.

public class InsuredController : Controller
  {
    private ISessionFactory _SessionFactory;  

    private int? currentPage=0;
    private int pageSize=25;

    //...

    public ActionResult Index(int? pageNumber)
    {      
      currentPage = pageNumber??0;

      ICriteria creteria = _SessionFactory.OpenSession().CreateCriteria(typeof(Foo.FooEntity));
      
      creteria.SetFirstResult(pageSize * (int)currentPage).SetMaxResults(pageSize);
      
      ViewResult vresult = View(creteria.List<Foo.FooEntity>());
      vresult.ViewData["PageNumber"] = pageNumber;
      return vresult;
    }
}

* This source code was highlighted with Source Code Highlighter.


Все бы хорошо, но дальше 0 страницы данные не возвращаются, а все потому что в базу уходит запрос
SELECT  *
 FROM  (SELECT  this_.ID AS ID1_0_0_,
          this_.CREATE_DATE AS CREATE2_0_0_,
          this_.DISABLE_DATE AS DISABLE3_0_0_,
          this_.EDIT_DATE AS EDIT4_0_0_,
          this_.EXCHANG_STAT AS EXCHANG5_0_0_
      FROM  FOO this_)
WHERE  ROWNUM BETWEEN 25 AND 75


* This source code was highlighted with Source Code Highlighter.


А вот оно что - BETWEEN vs ROWNUM.
А в школьном курсе оракловой физики четко написано что ROWNUM - это псевдостолбец, значение которого присваивается строке уже после выполнения предикатов запроса, но перед выполнением сортировок и агрегирований. В то же время оператор BETWEEN ограничивает выборку по столбцу значение которого еще не было присвоено, те равно NULL. А все операции сравнения чего либо с значением NULL = FALSE. Вот и получаем пустой результат.

Решение этой проблемы простое - заменить в конфиге значение своейства dialect - NHibernate.Dialect.OracleDialect на NHibernate.Dialect.Oracle10gDialect или NHibernate.Dialect.Oracle9iDialect

Результирующий запрос:
SELECT  *
 FROM  (SELECT  row_.*, ROWNUM rownum_
      FROM  (SELECT  this_.ID AS ID1_0_0_,
               this_.CREATE_DATE AS CREATE2_0_0_,
               this_.DISABLE_DATE AS DISABLE3_0_0_,
               this_.EDIT_DATE AS EDIT4_0_0_,
               this_.EXCHANG_STAT AS EXCHANG5_0_0_
           FROM  FOO this_) row_
      WHERE  ROWNUM <= :p0)
WHERE  rownum_ > :p1


* This source code was highlighted with Source Code Highlighter.

понедельник, 8 июня 2009 г.

.NET: Отладка приложений / сервисов

Замечательная штука отладчик. Не раз задумывался над проблемой отладки куска кода выполняемого при запуске приложения или сервиса. И вот нашел решение.
Вставляем код там где нужно зацепиться отладчиком, как только среда выполнения выполнит его появиться любимый диалог.


C#:
if (!Debugger.IsAttached) Debugger.Break();
* This source code was highlighted with Source Code Highlighter.

VB.NET:
If Not Debugger.IsAttached Then
  Debugger.Break()
End If

* This source code was highlighted with Source Code Highlighter.

среда, 3 июня 2009 г.

ORACLE: Перемещение таблиц и индексов пользователя в другой tablespace

собственно ответ на вопросы:
How to move LOB data to another tablespace?
How to move user tables to a different tablespace?
How to move user indexes to a different tablespace?

скрипт пока не умеет перемещать индекс-таблицы и секционированные таблицы.

  1. DECLARE
  2.   table_ts_name  VARCHAR2 (30) := 'USER_DATA'; –- табличное пространство для перемещения таблиц
  3.   index_ts_name  VARCHAR2 (30) := 'USER_INDEX'; –- табличное пространство для перемещения индексов
  4.   varUser VARCHAR2(30) := 'HR'; – схема объекты которой необходимо переместить
  5. BEGIN
  6.   FOR obj
  7.   IN ( -- перемещение таблиц содержащих поля LOB типов
  8.     SELECT 'alter table '||owner||'.'|| table_name||' move lob('|| column_name 
  9.         ||') store as (tablespace '|| table_ts_name move_sql
  10.      FROM  dba_tab_cols
  11.     WHERE  owner=varUser and data_type='%LOB'
  12.     UNION ALL
  13.     -- перемещение остальных таблиц   
  14.     SELECT 'alter table '||t1.owner|| '.'||t1.object_name||' move tablespace '||table_ts_name move_sql
  15.      FROM all_objects t1
  16.     WHERE t1.owner=varUser
  17.        AND t1.object_type = 'TABLE'
  18.        AND t1.temporary = 'N'
  19.        AND NOT EXISTS (
  20.                 SELECT 1 from dba_tab_cols t2
  21.                 where t1.owner = t2.owner
  22.                 AND t1.object_name = t2.table_name
  23.                 AND t2.data_type = 'LONG'
  24.                 AND t2.data_type = 'LONG RAW')
  25.     UNION ALL
  26.     -- перемещение и ребилд индексов, за исключением IOT индексов
  27.     SELECT 'alter index '||owner||'.'|| index_name|| ' rebuild tablespace '|| index_ts_name move_sql
  28.      FROM  all_indexes
  29.     WHERE  owner=varUser AND index_type <> 'IOT - TOP')
  30.   LOOP
  31.   dbms_output.put_line(obj.move_sql);
  32.    EXECUTE IMMEDIATE obj.move_sql;
  33.   END LOOP;
  34. END;
* This source code was highlighted with Source Code Highlighter.

понедельник, 1 июня 2009 г.

DateTime.ToString и "/" подстава

задолбался
      DateTime dt = DateTime.Now;
      Trace.WriteLine("ToString() - " + dt.ToString());
      Trace.WriteLine("dd/MM/yyyy HH:mm - " + dt.ToString("dd/MM/yyyy HH:mm"));
      Trace.WriteLine("dd[MM[yyyy HH^mm - " + dt.ToString("dd[MM[yyyy HH^mm"));
      Trace.WriteLine(@"dd\/MM\/yyyy HH:mm - " + dt.ToString(@"dd\/MM\/yyyy HH:mm"));
      Trace.WriteLine("System.Globalization.DateTimeFormatInfo.CurrentInfo.DateSeparator - " +
        System.Globalization.DateTimeFormatInfo.CurrentInfo.DateSeparator);


* This source code was highlighted with Source Code Highlighter.


Output:
ToString() - 01.06.2009 15:44:54
dd/MM/yyyy HH:mm - 01.06.2009 15:44
dd[MM[yyyy HH^mm - 01[06[2009 15^44
dd\/MM\/yyyy HH:mm - 01/06/2009 15:44
System.Globalization.DateTimeFormatInfo.CurrentInfo.DateSeparator - .

Спрашивается чем слеш(/) неугодил?

четверг, 14 мая 2009 г.

Сваял утилитку "Tfs BatchUndo"

Время от времени подваливают программеры с просьбой сделать откат CheckOut для файликов. Все бы хорошо, но Checkout они делали до переустановки операционки, или смены компа или имени. До того как меня достало я писал скрипт для этого, а теперь все это можно сделать с помощью утилитки TFS BatchUndo.

Интересная статья на данную тему Undoing a checkout that belongs to another user.