首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实体框架5.0 (C#):种子方法仅在更新数据库运行两次时运行

实体框架5.0 (C#):种子方法仅在更新数据库运行两次时运行
EN

Stack Overflow用户
提问于 2013-09-24 21:03:01
回答 1查看 3.7K关注 0票数 1

我有以下模型:

代码语言:javascript
复制
public class User
{
    public int UserId { get; set; }
    public string EmailAddress { get; set; }
    public byte[] PasswordHash { get; set; }
    public byte[] PasswordSalt { get; set; }

    public virtual List<Role> Roles { get; set; }
    public virtual List<Job> Jobs { get; set; }
    public virtual List<Project> Projects { get; set; }
    public virtual List<Submission> Submissions { get; set; }
    public virtual List<PROMembership> PROMemberships { get; set; }

    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Address { get; set; }
    public string ZipCode { get; set; }
    public string City { get; set; }
    public string Country { get; set; }
    public string Phone { get; set; }
    public string Notes { get; set; }
    public Guid? PasswordRetrievalToken { get; set; }

    [NotMapped]
    [Display(Name = "Full name")]
    public string FullName
    {
        get
        {
            if ((FirstName != null && FirstName.Length > 0) || (LastName != null && LastName.Length > 0))
            {
                return (FirstName + " " + LastName).Trim();
            }
            else
            {
                return EmailAddress;
            }
        }
    }
}

使用以下流畅的配置类:

代码语言:javascript
复制
public class UserConfiguration : EntityTypeConfiguration<User>
{
    public const int EmailAddressMinLength = 3;
    public const int EmailAddressMaxLength = 62;
    public const int FirstNameMaxLength = 50;
    public const int LastNameMaxLength = 50;
    public const int AddressMaxLength = 100;
    public const int ZipCodeMaxLength = 20;
    public const int CityMaxLength = 50;
    public const int CountryMaxLength = 50;
    public const int PhoneMaxLength = 50;
    public const int NotesMaxLength = 1000;

    public UserConfiguration()
    {
        ToTable("Users");
        HasKey(u => u.UserId).Property(u => u.UserId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        Property(u => u.EmailAddress).IsRequired();
        Property(u => u.EmailAddress).HasMaxLength(EmailAddressMaxLength);
        Property(u => u.PasswordHash).IsRequired();
        Property(u => u.PasswordSalt).IsRequired();
        Property(u => u.FirstName).HasMaxLength(FirstNameMaxLength);
        Property(u => u.LastName).HasMaxLength(LastNameMaxLength);
        Property(u => u.Address).HasMaxLength(AddressMaxLength);
        Property(u => u.ZipCode).HasMaxLength(ZipCodeMaxLength);
        Property(u => u.City).HasMaxLength(CityMaxLength);
        Property(u => u.Country).HasMaxLength(CountryMaxLength);
        Property(u => u.Phone).HasMaxLength(PhoneMaxLength);
        Property(u => u.Notes).HasMaxLength(NotesMaxLength);
        Property(u => u.PasswordRetrievalToken).IsOptional(); // somehow the DB is generated with this field required if this is ommited
        HasMany(u => u.Roles).WithMany(r => r.Users).Map(m => { m.MapLeftKey("UserId"); m.MapRightKey("RoleId"); m.ToTable("UsersInRoles"); });
        HasMany(u => u.Jobs).WithMany(j => j.Composers).Map(m => { m.MapLeftKey("UserId"); m.MapRightKey("JobId"); m.ToTable("ComposersInJobs"); });
    }
}

并使用此上下文配置类:

代码语言:javascript
复制
internal sealed class Configuration : DbMigrationsConfiguration<WebProject.DataAccess.WebProjectContext>
{
    private readonly bool _pendingMigrations;

    public Configuration()
    {
        AutomaticMigrationsEnabled = true;
        AutomaticMigrationDataLossAllowed = true;
        var migrator = new DbMigrator(this);
        _pendingMigrations = migrator.GetPendingMigrations().Any();
    }

    protected override void Seed(WebProject.DataAccess.WebProjectContext context)
    {
        if (!_pendingMigrations)
            return;
        // imagine seeding code here

到现在为止还好。当我执行Update-Database时,一切都按预期工作,Database被正确创建/更新,最后,我的Context-Configuration类中的种子方法被执行。

现在,我必须向模型中添加一些字段。使用Add-Migration命令:

代码语言:javascript
复制
public partial class AddClientRepresentation : DbMigration
{
    public override void Up()
    {
        AddColumn("dbo.Users", "MiddleName", c => c.String(maxLength: 50));
        AddColumn("dbo.Users", "Company", c => c.String(maxLength: 50));
        AddColumn("dbo.Users", "State", c => c.String(maxLength: 50));
        AddColumn("dbo.Users", "SecondaryPhone", c => c.String(maxLength: 50));
        AddColumn("dbo.Users", "SecondaryEmailAddress", c => c.String(maxLength: 62));
    }

    public override void Down()
    {
        DropColumn("dbo.Users", "SecondaryEmailAddress");
        DropColumn("dbo.Users", "SecondaryPhone");
        DropColumn("dbo.Users", "State");
        DropColumn("dbo.Users", "Company");
        DropColumn("dbo.Users", "MiddleName");
    }
}

所以我有以下几个类:

代码语言:javascript
复制
public class User
{
    public int UserId { get; set; }
    public string EmailAddress { get; set; }
    public byte[] PasswordHash { get; set; }
    public byte[] PasswordSalt { get; set; }

    public virtual List<Role> Roles { get; set; }
    public virtual List<Job> Jobs { get; set; }
    public virtual List<Project> Projects { get; set; }
    public virtual List<Submission> Submissions { get; set; }
    public virtual List<PROMembership> PROMemberships { get; set; }

    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }
    public string Company { get; set; }
    public string Address { get; set; }
    public string ZipCode { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Country { get; set; }
    public string Phone { get; set; }
    public string SecondaryPhone { get; set; }
    public string SecondaryEmailAddress { get; set; }
    public string Notes { get; set; }
    public Guid? PasswordRetrievalToken { get; set; }

    [NotMapped]
    [Display(Name = "Full name")]
    public string FullName
    {
        get
        {
            if ((FirstName != null && FirstName.Length > 0) || (LastName != null && LastName.Length > 0))
            {
                return (FirstName + " " + LastName).Trim();
            }
            else
            {
                return EmailAddress;
            }
        }
    }
}


public class UserConfiguration : EntityTypeConfiguration<User>
{
    public const int EmailAddressMinLength = 3;
    public const int EmailAddressMaxLength = 62;
    public const int FirstNameMaxLength = 50;
    public const int MiddleNameMaxLength = 50;
    public const int LastNameMaxLength = 50;
    public const int CompanyMaxLength = 50;
    public const int AddressMaxLength = 100;
    public const int ZipCodeMaxLength = 20;
    public const int CityMaxLength = 50;
    public const int StateMaxLength = 50;
    public const int CountryMaxLength = 50;
    public const int PhoneMaxLength = 50;
    public const int NotesMaxLength = 1000;

    public UserConfiguration()
    {
        ToTable("Users");
        HasKey(u => u.UserId).Property(u => u.UserId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        Property(u => u.EmailAddress).IsRequired();
        Property(u => u.EmailAddress).HasMaxLength(EmailAddressMaxLength);
        Property(u => u.PasswordHash).IsRequired();
        Property(u => u.PasswordSalt).IsRequired();
        Property(u => u.FirstName).HasMaxLength(FirstNameMaxLength);
        Property(u => u.MiddleName).HasMaxLength(MiddleNameMaxLength);
        Property(u => u.LastName).HasMaxLength(LastNameMaxLength);
        Property(u => u.Company).HasMaxLength(CompanyMaxLength);
        Property(u => u.Address).HasMaxLength(AddressMaxLength);
        Property(u => u.ZipCode).HasMaxLength(ZipCodeMaxLength);
        Property(u => u.City).HasMaxLength(CityMaxLength);
        Property(u => u.State).HasMaxLength(StateMaxLength);
        Property(u => u.Country).HasMaxLength(CountryMaxLength);
        Property(u => u.Phone).HasMaxLength(PhoneMaxLength);
        Property(u => u.SecondaryPhone).HasMaxLength(PhoneMaxLength);
        Property(u => u.SecondaryEmailAddress).HasMaxLength(EmailAddressMaxLength);
        Property(u => u.Notes).HasMaxLength(NotesMaxLength);
        Property(u => u.PasswordRetrievalToken).IsOptional(); // somehow the DB is generated with this field required if this is ommited
        HasMany(u => u.Roles).WithMany(r => r.Users).Map(m => { m.MapLeftKey("UserId"); m.MapRightKey("RoleId"); m.ToTable("UsersInRoles"); });
        HasMany(u => u.Jobs).WithMany(j => j.Composers).Map(m => { m.MapLeftKey("UserId"); m.MapRightKey("JobId"); m.ToTable("ComposersInJobs"); });
    }
}

当我现在运行Update-Database时,迁移运行得很好,但是Seed方法没有执行(不管我是否使用-Force)。如果我再次运行Update-Database命令,则会执行seed方法,但会立即返回,因为没有挂起的迁移。

我一步一步地研究它,发现如果我注释掉EntityTypeConfiguration中的所有新字段(MiddleName、公司、州、SecondaryPhone、SecondaryEmailAddress),种子方法就会在我第一次运行更新命令时执行,没有任何问题。

有没有人遇到过同样的问题?可能的原因是什么?

EN

回答 1

Stack Overflow用户

发布于 2013-09-24 21:07:21

我猜这段代码就是罪魁祸首:

代码语言:javascript
复制
if (!_pendingMigrations)
    return;

这就解释了为什么它只会运行第二次,因为在这一点上你没有任何挂起的迁移。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18982394

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档