我有以下模型:
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 类中的种子方法被执行。
现在我必须在模型中添加一些字段。使用添加迁移命令:
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),则在我第一次运行更新命令时执行种子方法而没有任何问题。
有没有人遇到过同样的问题?可能是什么原因?