This project is read-only.

ПРОЕКТ

ОДНАЖДЫ ЗАДАННЫЕ ИЛИ ЕЩЁ НЕ ЗАДАННЫЕ ВОПРОСЫ

Вопрос: Как мне произвести запись в журнал отладочных данных?
Ответ: Проект использует компоненты Enterprise Library для управления журналами (logs). На данный момент проект настроен на запись журнала в простой текстовый файл %APPDATA%\UD\trace.log. Самый простой смособ записать строку в журнал, воспользоваться методом void void LogMessage(string logMessage) класса MContracts.App через объект-одиночку App:

class MyClass
{
   public string MyProperty
   {
        get
        {
              App.LogMessage("Чтение свойства MyClass.MyProperty");
              return _propertyValue;  
        }
        set
        {
              App.LogMessage("Запись свойства MyClass.MyProperty: " + value);
              _propertyValue = value;  
        }
   }
}

Вопрос: Почему у меня в поле ввода даты отображается надпись на английском языке Select a date?
Ответ: У Вас не установлен языковой пакет с поддержкой русского языка для Microsoft .NET 4. Получить языковой пакет можно по адресу http://www.microsoft.com/downloads/ru-ru/details.aspx?FamilyID=7a4c6414-7f64-47a5-ae20-218403137957. После установки может понадобится перезагрузка компьютера, что бы изменения вступили в силу.

Вопрос: Как изменить модель БД в проекте?
Ответ: Выполните такие действия:
  1. Изменить модель БД в Visual Paradigm
  2. Сгенерировать скрипт БД, воспользовавшись командой Generate Database... в меню ORM. У меня в модели настроено, что бы скрипт сбрасывался в UDDB->Scripts->Model.ddl, но путь UDDB у каждого, конечно, свой
  3. Скопировать весь текст из Model.ddl в Model.sql, что бы запустить его через Visual Studio, а то *.ddl не понимает оно. Можно этого не делать, если используется другая программа работы с Oracle.
  4. Изменить расположение ALTER TABLE, переместив их в конец файла, что бы ограничения накладывались позже, чем производилась вставка тестовых данных. Visual Paradigm не умеет определять зависимости по данным и вставляет их в произвольном порядке в таблицы.
  5. Открыть в проекте McDataContext.lqml
  6. Через контектсное меню на дизайнере модели выбрать Update Model from Database... и выполнить синхронизацию модели ORM с БД.
  7. Изменения должны отразиться.

Вопрос: Я изменил модель McDataContext.lqml и у меня проект перестал компилироваться (или проект компилируется, но многие функции сохранения данных в БД не работают. Что мне делать?
Ответ: Скорее всего проблема вызвана генерацией кода по модели (генерация McDataContext.Designer.сs на базе модели McDataContext.lqml). Дело в том, что в проекте используется модифицированный генератор кода, который отличается от LinqGenerator тем, что автоматически назначает объект Sequence свойствам, которые помечены в качестве первичного ключа и носят имя "ID". Подразумевается, что имя Sequence объектов имеет имя seq_<Имя таблицы>: имеено так задано в модели БД в проеке model.vpp для Visual Paradigm. Шаблон генератора входит в проект (Документы\UPGeneratorTemplate.tmpl).
В результате перестановки Visual Studio или по другим причинам генератор UDGeneratorTemplate.tmpl заменяется на стандартный, что и приводит к ошибкам в программе. Что бы установить для модели генератор UDGeneratorTemplate.tmpl, необходимо:
  1. Вызвать команду Templates... в меню Tools->Entity Developer в Visual Studio
  2. Нажать New...
  3. Скопировать содержимое UDGeneratorTemplate.tmpl в окно редактирования
  4. Установить Template Name как UDGeneratorTemplate (Хотя любое другое имя так же подходит)
  5. Сохранить шаблон по любым именем
  6. Открыть на редактирование McDataContext.lqml
  7. Вызвать контекстное меню на диаграмме и выбрать пункт Edit Model Properties...
  8. В диалоговом окне для пункта Generation выбрать шаблон UDGeneratorTemplate.
  9. Закрыть окно, нажав ОК.
  10. Если генерация прошла успешно, то код McDataContext.designer.cs будет содержать все классы, соответствующие модели и для всех ID(PK) будет установлен атрибут с именем Sequence.

Вопрос: В каких случаях и как реализовывать IDataErrorInfo?
Ответ: Этот интерфейс реализуется для тех классов, свойства которых будут иметь привязку к пользовательским элементам управления и их значения будут таким образом изменяться пользователями, при этом необходимо иметь возможность проверки удовлетворения значения свойства некоторым ограничениям (бизнес-правилам). Интерфейс имеет два свойства: string this[string propertyName] {get;} реализация которого в классе должна вернуть сообщение об ошибке, если свойство с именем propertyName не удовлетворяет ограничениям, либо string.Empty - в противном случае. Второе свойство: string Error{get;} - возвращает описание ошибки для целого объекта, либо string.Empty, если состояние объекта не содержит ошибок.
Так как объекты могут обладать многими свойствами и иметь сложную взаимосвяь проверки свейств в виду зависимостей между ними, то реализация свойства string this[string propertyName] {get;} имеет тенденцию к разбуханию. К тому же наблюдаются проблемы с повторным использованием кода, отвечающего за проверку состояния свойства. Для решения этих проблем в проект введён интерфейс IDataErrorHandler<in T>
public interface IDataErrorHandler<in T>
{
     string GetError(T source, string propertyName, ref bool handled);
}

Метод GetError интерфейса реализуется классами, которые ответственны за проверку свойства (propertyName) объекта типа T. Метод возвращает сообщение об ошибке в значении свойства и флаг handled, который устанавливается в значение Истина, если класс обработал значение свойства. Установка флага позволяет прерывать цепочку вызовов в коллекции обработчиков (по шаблону Chain of responsibility). Для реализации этого поведения в проект введён класс DataErrorHandlers<T> : List<IDataErrorHandler<T>>:
public class DataErrorHandlers<T> : List<IDataErrorHandler<T>>
{
        public string HandleError(T sender, string propertyName)
        {
             string result;
             bool handled = false;
             foreach (var item in this)
             {
                 result = item.GetError(sender, propertyName, ref handled);
                 if (handled)
                     return result;
             }
             return string.Empty;
       }
}
Пример использования классов обработчиков ошибок и класса коллекции обработчиков можно посмотреть в проекте в классе http://mc.codeplex.com/SourceControl/changeset/view/5138#79218.
Ещё несколько замечаний:
  1. Если в классе есть свойства, которые не могут принимать значение null, то добавьте в коллекцию обработчиков стандартный обработчик ошибок для не-null полей DataErrorHandlerForNonNullable<T>.
  2. Если необходимо реализовать свойство IDataErrorInfo.Error, то можно воспользоваться классом методом DataErrorInfoValidator.Validate, который опросит все свойства объекта на наличие в нём ошибок и вернёт в виде одной строки с разделением ошибок символом \n:
class MyClass : IDataErrorInfo
{ 
   public string Error
   {
      get
      {
          return this.Validate();
      }
   }
  private readonly DataErrorHandlers<MyClass > _errorHandlers = new DataErrorHandlers<MyClass >()
                                                                             {
                                                                                 new DataErrorHandlerForNonNullable<MyClass >(){ErrorMessage = "Не задано значение поля"}  
  public string this[string propertyName]
  {
       get
       {
                 return _errorHandlers.HandleError(this, columnName);       
       }
  }
} 

Вопрос: Я пишу тест, в котором мне нужен доступ к экземпляру LinqContractRepository. Как его лучше получить?
Ответ: В проекте MTests есть класс LinqContractRepositoryTest. Воспользуйтесь статическим методом класса CreateLinqContractRepository() для получения экземпляра:
using (var repository = LinqContractRepositoryTest.CreateLinqContractRepository())
{
     // У LinqContractRepository есть доступ к созданному контексту:
     McDataContext ctx = repository.Context;
}

Last edited Mar 8, 2011 at 7:19 PM by fmarakasov, version 9

Comments

desman Feb 21, 2011 at 2:37 PM 
надо этот раздел переименовать в "однажды заданные вопросы" ))