gpt4 book ai didi

c# - EF 代码优先 : separate creation of objects in db with TFT inheritance

转载 作者:太空宇宙 更新时间:2023-11-03 14:06:04 27 4
gpt4 key购买 nike

用例示例

用户已在网站上注册(向用户表添加记录)。然后转到电子邮件并确认注册。确认链接重定向到人员编辑表单页面,用户填写表单并提交(向人员表添加记录)。

技术说明

我在 EF 模型中定义了一个简单的 2 对象表类型继承。

实体

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

需要在 DbSet 中一致地创建链接 (FK) 对象,如下所示:

    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 个验证错误。

如何在FK(继承)关联的DbSets中单独添加条目?

更新

我找到了一个解决方案。但是为此您必须删除旧用户。我想在不删除的情况下执行此操作,因为如果 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();

但是还有另一个问题 - 为 person 对象生成了一个新的 Guid。

如何在不删除用户旧记录的情况下解决问题?

最佳答案

包含用例更新后:

你不应该在这里使用继承。您应该在实体之间使用组合和一对一关系:

public class User
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public virtual UserInfo Information{get;set;}
}

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

public class UserInfo
{
[ForeignKey("InfosUser")]
[Key]
public UserId {get;set;}
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public virtual User InfosUser {get;set;}
}

internal class UserInfoConfiguration : EntityTypeConfiguration<UserInfo>
{
internal UserInfoConfiguration()
{
ToTable("Persons");

Property(x => x.FirstName)
.IsRequired()
.HasMaxLength(16);
Property(x => x.MiddleName)
.IsOptional()
.HasMaxLength(16);
Property(x => x.LastName)
.IsRequired()
.HasMaxLength(16);
HasRequired(ui=>ui.InfosUser).WithOptional(u=>u.Information)
}
}

并使用它:

    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 user = db.GetPersonFromDb(Id);// Get early saved person from db
var information = new UserInfo
{
FirstName = "someFirstName",
LastName = "someLastName",
}
user.Information = information;
db.SaveChanges();

关于c# - EF 代码优先 : separate creation of objects in db with TFT inheritance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9279679/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com