Как установить значение по умолчанию для POCO в EF CF? - PullRequest
46 голосов
/ 29 июня 2010

В подходе Entity Framework Code First, как установить значение по умолчанию для свойства в классе EntityConfiguration POCO?

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime CreatedOn { get; set; }
}

public class PersonConfiguration : EntityConfiguration<Person>
{
    public PersonConfiguration()
    {
        Property(p => p.Id).IsIdentity();
        Property(p => p.Name).HasMaxLength(100);

        //set default value for CreatedOn ?
    }
}

Ответы [ 7 ]

24 голосов
/ 24 февраля 2012

С выпуском Entity Framework 4.3 вы можете сделать это с помощью Migrations.

EF 4.3 Код Пошаговое руководство по первой миграции

Так что, используя ваш пример, это будет что-то вроде:

public partial class AddPersonClass : DbMigration
{
    public override void Up()
    {
        CreateTable(
            "People",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),
                    Name = c.String(maxLength: 100),
                    CreatedOn = c.DateTime(nullable: false, defaultValue: DateTime.UtcNow)
                })
            .PrimaryKey(t => t.Id);
    }

    public overide void Down()
    {
        // Commands for when Migration is brought down
    }
}
15 голосов
/ 01 июня 2011

Вы можете установить значения по умолчанию с помощью конструктора для класса.Вот класс, который у меня есть в моем текущем проекте с использованием MVC3 и Entity Framework 4.1:

namespace MyProj.Models
{
using System;
using System.Collections.Generic;

public partial class Task
{
    public Task()
    {
        this.HoursEstimated = 0;
        this.HoursUsed = 0;
        this.Status = "To Start";
    }

    public int ID { get; set; }
    public string Description { get; set; }
    public int AssignedUserID { get; set; }
    public int JobID { get; set; }
    public Nullable<decimal> HoursEstimated { get; set; }
    public Nullable<decimal> HoursUsed { get; set; }
    public Nullable<System.DateTime> DateStart { get; set; }
    public Nullable<System.DateTime> DateDue { get; set; }
    public string Status { get; set; }

    public virtual Job Job { get; set; }
    public virtual User AssignedUser { get; set; }
}
}
7 голосов
/ 31 мая 2012

Я знаю, что эта тема продолжается какое-то время, и я подошел к той же проблеме. До сих пор я не смог найти для меня решение, которое бы держало все это вместе в одном месте, чтобы код все еще читался.

При создании пользователя я хочу, чтобы некоторые поля устанавливались самим объектом через private setters, например, GUID и дата создания, а не «загрязнение» конструктора.

Мой класс пользователя:

public class User
{
    public static User Create(Action<User> init)
    {
        var user = new User();
        user.Guid = Guid.NewGuid();
        user.Since = DateTime.Now;
        init(user);
        return user;
    }

    public int UserID { get; set; }

    public virtual ICollection<Role> Roles { get; set; }
    public virtual ICollection<Widget> Widgets { get; set; }

    [StringLength(50), Required]
    public string Name { get; set; }
    [EmailAddress, Required]
    public string Email { get; set; }
    [StringLength(255), Required]
    public string Password { get; set; }
    [StringLength(16), Required]
    public string Salt { get; set; }

    public DateTime Since { get; private set; }
    public Guid Guid { get; private set; }
}

Телефонный код:

context.Users.Add(User.Create(c=>
{
    c.Name = "Name";
    c.Email = "some@one.com";
    c.Salt = salt;
    c.Password = "mypass";
    c.Roles = new List<Role> { adminRole, userRole };
}));
4 голосов
/ 29 июня 2010
3 голосов
/ 23 мая 2014

В случае, если вы хотите, чтобы SQL Server предоставлял дату по умолчанию, как вы этого добились, важная часть - defaultValueSql: "GETDATE ()", которая установит сервер SQL по умолчанию, а не только оценивает времяскрипт был запущен (т.е. DateTime.UtcNow)

   public partial class AddPersonClass : DbMigration
    {
    public override void Up()
    {
        CreateTable(
            "People",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),
                    Name = c.String(maxLength: 100),
                    CreatedOn = c.DateTime(nullable: false, defaultValueSql: "GETDATE()")
                })
            .PrimaryKey(t => t.Id);
    }

    public overide void Down()
    {
        // Commands for when Migration is brought down
    }
}
3 голосов
/ 03 апреля 2013

Я не уверен, с какой версией EF это станет доступно, но с версией 5 наверняка вы справитесь с этим. Просто установите значение по умолчанию GetDate () для столбца в SQL, либо в TSQL, либо в конструкторе, а затем настройте классы EF следующим образом:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime CreatedOn { get; set; }
}

public class PersonConfiguration : EntityConfiguration<Person>
{
    public PersonConfiguration()
    {
        Property(p => p.Id).IsIdentity();
        Property(p => p.Name).HasMaxLength(100);

        this.Property(p => p.CreatedOn ).HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Computed);
    }
}

Обратите внимание, что вам не нужно делать столбец базы данных обнуляемым или свойство POCO.

0 голосов
/ 24 мая 2017

Нет другого способа, кроме как использовать МИГРАЦИИ БД и для включения миграций вы должны установить свое свойство следующим образом

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]        
    public DateTime CreatedOn { get; set; }

И после этого, как только ваша база данных будет создана, вы должнывыполните следующие шаги, чтобы включить миграции.Перейдите в консоль диспетчера программ и выполните следующие команды одну за другой:

  • PM> Enable-Migrations
  • PM> Add-Migration AlterMyTable Здесь AlterMyTable может иметь любое имя.это создаст файл в новой добавленной папке Migrations в вашем решении currentTimestamp_AlterMyTable.cs -Скопируйте следующее в метод Up currentTimestamp_AlterMyTable.cs
  • AlterColumn("Person", "CreatedOn", n => n.DateTime(nullable: false, defaultValueSql: "SYSUTCDATETIME()")); И после этого выполните последнююкоманда в консоли диспетчера программ
  • PM> Update-Database И теперь, если вы видите таблицу Person в своей базе данных и затем перейдете к столбцу CreatedOn, она должна иметь значение по умолчанию как SYSUTCDATETIME(), т.е.если вы попытаетесь вставить некоторые данные в эту таблицу, ваша база данных автоматически обновит для вас этот столбец CreatedOn.
...