не установка свойства даты для объекта приводит к ошибке - PullRequest
4 голосов
/ 29 ноября 2010

У меня есть таблица с полем smalldatetime NOT NULL со значением по умолчанию getdate(). При создании новой записи в таблице я не устанавливаю поле smalldatetime в коде через синтаксис LINQ To SQL, я просто позволяю базе данных установить значение по умолчанию, которое является текущей датой. Если я не установлю это явно в коде, он выдаст следующую ошибку:

Переполнение SqlDateTime. Должно быть между 01.01.1753 12:00:00 и 31.12.9999 11:59:59 вечера.

Если я устанавливаю значение по умолчанию в базе данных, почему я должен установить его в коде? Я заметил странные вещи с датами, когда дело доходит до LINQ To SQL.

Ответы [ 4 ]

3 голосов
/ 29 ноября 2010

Вместо того, чтобы устанавливать поле как IsDbGenerated, вы можете рассмотреть возможность установки его значения AutoSync на OnInsert.IsDbGenerated не позволит вам установить значение поля когда-либо (что может быть тем, что вы хотите для поля «дата создания», но не для поля «последнего изменения»).

Однако, если вы 'Если вы используете ORM, я бы попросил вас подумать, хотите ли вы, чтобы логика вашего приложения использовалась как в базе данных, так и в коде приложения.Имеет ли смысл реализовывать значение по умолчанию в коде (через частичные методы , например Insert[Entity])?

1 голос
/ 29 ноября 2010

Вы должны установить сгенерированное свойство так, чтобы LINQ to SQL не отправлял его значение по умолчанию для создания.

Свойство на объекте называется «Автоматически сгенерированное значение».

alt text

0 голосов
/ 29 ноября 2010

Чтобы обойти это, убедитесь, что ваша модель LINQ To SQL знает, что ваше поле smalldatetime автоматически сгенерировано базой данных.

Выберите поле таблицы на диаграмме LINQ To SQL и найдитеОкно свойств.Установите для свойства Автоматически сгенерированное значение значение True .Это гарантирует, что поле НЕ будет включено в оператор INSERT, созданный LINQ To SQL.

alt text

В качестве альтернативы, вы должны указать это самостоятельно:

if (newCustomer.DateTimeCreated == null) {
       newCustomer.DateTimeCreated = DateTime.Now; // or UtcNow 
 }
0 голосов
/ 29 ноября 2010

LINQ To SQL не соблюдает значения по умолчанию для базы данных, чтобы впоследствии можно было обновить значение. Чтобы разрешить это, вам нужно установить значения по умолчанию в вашем коде.

При создании новых объектов NOT NULL с базой данных по умолчанию C # будет использовать значения по умолчанию, такие как MinValue для чисел и дат, пустые GUID (нули) и т. Д. Вы можете искать эти условия и заменять ваше собственное значение по умолчанию.

Это известная проблема разработки в LINQ To SQL. Подробное обсуждение см. По этой ссылке:

http://www.codeproject.com/KB/linq/SettingDefaultValues.aspx

Пример кода для установки значений по умолчанию в вашем приложении:

private void SetDefaults(object LinqObj)
{
    // get the properties of the LINQ Object
    PropertyInfo[] props = LinqObj.GetType().GetProperties();

    // iterate through each property of the class
    foreach (PropertyInfo prop in props)
    {
        // attempt to discover any metadata relating to underlying data columns
        try
        {
            // get any column attributes created by the Linq designer
            object[] customAttributes = prop.GetCustomAttributes
            (typeof(System.Data.Linq.Mapping.ColumnAttribute), false);

            // if the property has an attribute letting us know that 
            // the underlying column data cannot be null
            if (((System.Data.Linq.Mapping.ColumnAttribute)
            (customAttributes[0])).DbType.ToLower().IndexOf("not null") != -1)
            {
                // if the current property is null or Linq has set a date time 
            // to its default '01/01/0001 00:00:00'
                if (prop.GetValue(LinqObj, null) == null || prop.GetValue(LinqObj, 
                null).ToString() == (new DateTime(1, 1, 1, 0, 0, 0)).ToString())
                {

                    // set the default values here : could re-query the database, 
                    // but would be expensive so just use defaults coded here
                    switch (prop.PropertyType.ToString())
                    {
                        // System.String / NVarchar
                        case "System.String":
                            prop.SetValue(LinqObj, String.Empty, null);
                            break;
                        case "System.Int32":
                        case "System.Int64":
                        case "System.Int16":
                            prop.SetValue(LinqObj, 0, null);
                            break;
                        case "System.DateTime":
                            prop.SetValue(LinqObj, DateTime.Now, null);
                            break;
                    }
                }
            }
        }
        catch
        {
            // could do something here ...
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...