1

私は次のモデルを持っています:

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;
            }
        }
    }
}

次の流暢な構成クラスを使用します。

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"); });
    }
}

そして、このコンテキスト構成クラスで:

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 を実行すると、すべてが期待どおりに機能し、データベースが正しく作成/更新され、最終的に Context-Configuration クラスのシード メソッドが実行されます。

ここで、モデルにいくつかのフィールドを追加する必要がありました。Add-Migration コマンドの使用:

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");
    }
}

そして、私は次のクラスを持っています:

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 コマンドをもう一度実行すると、シード メソッドが実行されますが、保留中の移行がないため、すぐに戻ります。

段階的に掘り下げたところ、EntityTypeConfiguration のすべての新しいフィールド (MiddleName、Company、State、SecondaryPhone、SecondaryEmailAddress) をコメントアウトすると、最初に Update コマンドを何も指定せずに実行したときにシード メソッドが実行されることがわかりました。問題。

誰かが同じ問題を経験しましたか? その理由は何ですか?

4

1 に答える 1

0

このコードが犯人だと思います:

if (!_pendingMigrations)
    return;

その時点で保留中の移行がないため、2 回目のみ実行される理由は理にかなっています。

于 2013-09-24T13:07:20.930 に答える