Значения столбца SQL Server по умолчанию в Entity Framework 4 POCO - PullRequest
2 голосов
/ 17 июня 2011

Я сгенерировал EDMX из существующей базы данных, которая содержит значения столбцов по умолчанию. У меня также есть объект POCO, созданный с помощью шаблона T4.

Теперь у меня есть сценарий, в котором я хочу создать POCO и сохранить его в базе данных следующим образом:

dim tablePocoEntityInstance as New tablePocoEntity
context.MsSQLTable.AddObject(tablePocoEntityInstance)
context.SaveChanges()

Работает нормально, за исключением значений по умолчанию, установленных в базе данных SQL Server.

Например:

Таблица SQL Server

  id (int, not null, auto increament)
  magicNR (int, not null, defaultValue = 11)

Сгенерированный объект POCO имеет два свойства:

Partial Public Class tablePocoEntity
    Public Overridable Property id As Integer
    Public Overridable Property magicNR As Integer
...

Проблема в том, что magicNR не имеет значения nullable и неявно инициализируется. Когда я сохраняю объект, id - это как и должно быть, но magicNR имеет значение 0, а не 11, которое является значением по умолчанию.

Мои вопросы:

  1. Могу ли я настроить свои сущности таким образом, чтобы они использовали значения столбцов базы данных по умолчанию?
  2. Если нет, то как я могу установить значения по умолчанию в коде?
  3. Как лучше всего решить эту проблему?

Ответы [ 3 ]

2 голосов
/ 02 ноября 2011

Откройте вашу сущность .edmx, щелкните правой кнопкой мыши на поле данных и выберите свойства.В DataBaseScriptGeneration измените StoreGeneratedPattern на «Вычисленный».После того, как это установлено, ваше приложение будет работать как положено - где SQL Server вставляет значение по умолчанию.Однако вы не сможете принудительно установить значение со стороны приложения.

1 голос
/ 17 июня 2011

Не существует готового решения, о котором я бы знал, но поскольку эти классы POCO генерируются из базы данных с использованием шаблонов T4, вы всегда можете изменить эти шаблоны для проверки базы данных, а также для поиска и соблюдениязначения по умолчанию для столбцов.

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

0 голосов
/ 02 ноября 2015

Хорошо, этот вопрос довольно старый, но все же я хотел бы поделиться своим решением этого вопроса.

Что я сделал, так это изменил шаблон T4, чтобы добавить частичный метод ко всем сгенерированным объектам и вызвать его из конструктора. Этот частичный метод реализован в расширенном частичном классе, который вы создадите вручную для каждой сущности, для которой нужно установить значения по умолчанию.

Примечание: я использую EF6

Короткие шаги:

1) Измените шаблон T4, включив частичный метод, подобный этому:

partial void OnCreationComplete();

2) Измените шаблон T4, чтобы вызвать этот метод в конструкторе

OnCreationComplete();

3) Создайте частичный класс для тех объектов, которым необходимо установить свойство по умолчанию, и реализуйте метод OnCreationComplete:

partial void OnCreationComplete()
{
    PropertyFoo = "Bar";
}

Вот полный код:

Шаблон T4

// You might want to remove the IF statement that excludes the constructor generation for entities without collection and complex entities...
<#
    var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity);
    var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity);
    var complexProperties = typeMapper.GetComplexProperties(entity);
#>
    public <#=code.Escape(entity)#>()
    {
<#
        foreach (var edmProperty in propertiesWithDefaultValues)
        {
#>
        <#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
<#
        }

        foreach (var navigationProperty in collectionNavigationProperties)
        {
#>
        <#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>();
<#
        }

        foreach (var complexProperty in complexProperties)
        {
#>
        <#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
<#
        }
#>
        OnCreationComplete();
    }

    partial void OnCreationComplete();

Пример сгенерированного класса:

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated from a template.
//
//     Manual changes to this file may cause unexpected behavior in your application.
//     Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace MyTest.DAL
{

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;

    public partial class Foo
    {
        public Foo()
        {
            OnCreationComplete();
        }

        partial void OnCreationComplete();

        public string MyPropertyFoo { get; set; }

    }
}

Расширенный частичный класс

public partial class Foo
{
    partial void OnCreationComplete()
    {
        MyPropertyFoo = "Bar";
    }
}

Надеюсь, это кому-нибудь поможет ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...