Пример использования
Пользователь зарегистрировался на сайте (добавление записи в таблицу Users).Затем переходит на электронную почту и подтверждает регистрацию.Ссылка для подтверждения перенаправляет на страницу с формой редактирования человека, пользователь заполняет форму и отправляет ее (добавляя запись в таблицу Персоны).
Техническое описание
У меня естьПростое 2-х объектное наследование Table-Per-Type, определенное в модели EF.
Объекты
public class User
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Password { get; set; }
}
public class Person : User
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
}
База данных
public class MainDataContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Person> Persons { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
var configs = modelBuilder.Configurations;
configs.Add(new UserConfiguration());
configs.Add(new PersonConfiguration());
}
}
Конфигурации
internal class UserConfiguration : EntityTypeConfiguration<User>
{
internal UserConfiguration()
{
ToTable("Users");
HasKey(x => x.Id);
Property(x => x.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(x => x.Name)
.IsRequired()
.HasMaxLength(128);
Property(x => x.Password)
.IsRequired()
.HasMaxLength(128);
Property(x => x.Email)
.IsRequired()
.HasMaxLength(128);
}
}
internal class PersonConfiguration : EntityTypeConfiguration<Person>
{
internal PersonConfiguration()
{
ToTable("Persons");
Property(x => x.FirstName)
.IsRequired()
.HasMaxLength(16);
Property(x => x.MiddleName)
.IsOptional()
.HasMaxLength(16);
Property(x => x.LastName)
.IsRequired()
.HasMaxLength(16);
}
}
Необходимо последовательно создавать связанные объекты (FK) в DbSets, что-то вроде этого:
var db = new MainDataContext();
var user = new User
{
Name = "someUser",
Password = "somePassword",
Email = "someEmail"
};
db.Users.Add(user);
db.SaveChanges();
// After some time in other some place
var person = new Person
{
Id = user.Id,
FirstName = "someFirstName",
LastName = "someLastName"
};
db.Persons.Add(person);
db.SaveChanges();
После последнегоSaveChanges DbEntityValidationError было обнаружено: «Проверка не удалась для одной или нескольких сущностей. Для получения дополнительной информации см. Свойство EntityValidationErrors».Есть 3 ошибки проверки для обязательных полей пользователя.
Как отдельно добавить записи в DbSets, связанные с FK (наследование)?
UPDATE
Я нашел одно решение.Но для этого вы должны удалить старого пользователя.Я хотел бы сделать это без удаления, потому что, если таблица Users будет связана с другими таблицами, то это сделает невозможным удаление.
var db = new MainDataContext();
var user = new User
{
Name = "someUser",
Password = "somePassword",
Email = "someEmail"
};
db.Users.Add(user);
db.SaveChanges();
// After some time in other some place
var person = new Person
{
Id = user.Id,
Name = user.Name,
Password = user.Password,
Email = user.Email,
FirstName = "someFirstName",
LastName = "someLastName"
};
db.Users.Remove(user);
db.Persons.Add(person);
db.SaveChanges();
Но возникла другая проблема - генерируется новый Guid для объекта person.
Как решить проблему, не удаляя старую запись пользователя?