实体框架中的一对一或零关系,两个实体都有自己的pkk
本文关键字:实体 两个 pkk 自己的 框架 一对一 关系 | 更新日期: 2023-09-27 18:04:52
我试图在实体框架中创建一对一或零关系,两个实体都有自己的pk,但我不能
public class EmployeeBank
{
[Key]
public int Id {get;set;}
public Name {get;set;}
public virtual EmployeePaymentMethod EmployeePaymentMethod { get; set; }
}
public class EmployeePaymentMethod
{
[Key]
public int Id {get;set;}
public virtual EmployeeBank EmployeeBank {get;set;}
}
public class EmployeeBankMapping : EntityTypeConfiguration<EmployeeBank>
{
public EmployeeBankMapping()
{
this.HasRequired(z => z.EmployeePaymentMethod)
.WithOptional(zz => zz.EmployeeBank)
.Map(zzz => zzz.MapKey("EmployeePaymentMethodId"));
}
}
如果实现上面的代码,我发现在数据库中创建了一对多的关系。我怎样才能做到这一点呢?
这是使用DataAnnotations
。
public class EmployeeBank
{
public int Id {get;set;}
public string Name {get;set;}
public virtual EmployeePaymentMethod EmployeePaymentMethod { get; set; }
}
public class EmployeePaymentMethod
{
[Key, ForeignKey("EmployeeBank ")]
public override int Id {get;set;}
public virtual EmployeeBank EmployeeBank {get;set;}
}
这里使用的是Fluent API
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<EmployeeBank>()
.HasOptional(e => e. EmployeePaymentMethod) // Mark EmployeePaymentMethod property optional in EmployeeBank entity
.WithRequired(b => b. EmployeeBank); // mark EmployeeBank property as required in EmployeePaymentMethod entity. Cannot save EmployeePaymentMethod without EmployeeBank
}
您可以使用以下解决方案:
public class EmployeeContext : DbContext
{
public DbSet<EmployeeBank> EmployeeBanks { get; set; }
public DbSet<EmployeePaymentMethod> EmployeePaymentMethods { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<EmployeeBank>()
.HasMany(e => e.DoNotUseMeSir)
.WithMany(b => b.DoNotUseMeSir)
.Map(mc => mc.ToTable("BankToPaymentMethods")
.MapLeftKey("EmployeeBankId")
.MapRightKey("EmployeePaymentMethodId"));
}
}
public class EmployeeBank
{
public EmployeeBank()
{
DoNotUseMeSir = new List<EmployeePaymentMethod>();
}
public int EmployeeBankId { get; set; }
public string Name {get;set;}
[NotMapped]
public EmployeePaymentMethod EmployeePaymentMethod
{
get { return DoNotUseMeSir.FirstOrDefault(); }
set
{
DoNotUseMeSir.Clear();
DoNotUseMeSir.Add(value);
}
}
public virtual ICollection<EmployeePaymentMethod> DoNotUseMeSir { get; set; }
}
public class EmployeePaymentMethod
{
public EmployeePaymentMethod()
{
DoNotUseMeSir = new List<EmployeeBank>();
}
public int EmployeePaymentMethodId { get; set; }
[NotMapped]
public EmployeeBank EmployeeBank
{
get { return DoNotUseMeSir.FirstOrDefault(); }
set
{
DoNotUseMeSir.Clear();
DoNotUseMeSir.Add(value);
}
}
public virtual ICollection<EmployeeBank> DoNotUseMeSir { get; set; }
}
public class EmployeeDatabaseInitialiser : CreateDatabaseIfNotExists<EmployeeContext>
{
protected override void Seed(EmployeeContext context)
{
base.Seed(context);
var employeeBankIdUc =
"ALTER TABLE dbo.BankToPaymentMethods ADD CONSTRAINT uq_BankToPaymentMethods_EmployeeBankId UNIQUE(EmployeeBankId)";
context.Database.ExecuteSqlCommand(employeeBankIdUc);
var employeePaymentMethodIdUc =
"ALTER TABLE dbo.BankToPaymentMethods ADD CONSTRAINT uq_BankToPaymentMethods_EmployeePaymentMethodId UNIQUE(EmployeePaymentMethodId)";
context.Database.ExecuteSqlCommand(employeePaymentMethodIdUc);
}
}
然后简单地使用:
Database.SetInitializer(new EmployeeDatabaseInitialiser());
new EmployeeContext().Database.Initialize(true);
var context = new EmployeeContext();
var bank1 = new EmployeeBank{Name = "Bank1"};
var bank2 = new EmployeeBank {Name = "Bank2"};
var epm1 = new EmployeePaymentMethod();
var epm2 = new EmployeePaymentMethod();
context.EmployeeBanks.Add(bank1);
context.EmployeeBanks.Add(bank2);
context.EmployeePaymentMethods.Add(epm1);
context.EmployeePaymentMethods.Add(epm2);
context.SaveChanges();
bank1.EmployeePaymentMethod = epm1;
epm2.EmployeeBank = bank2;
context.SaveChanges();
我对两个关系列使用了带有附加UNIQUE约束的多对多关系,这将它变成了一对一对的关系。你也有独立的自增id。这个解决方案不是100%的实体框架,需要自定义数据库初始化器来放置约束。