实体框架中的一对一或零关系,两个实体都有自己的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"));
        }
 }

如果实现上面的代码,我发现在数据库中创建了一对多的关系。我怎样才能做到这一点呢?

实体框架中的一对一或零关系,两个实体都有自己的pkk

这是使用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%的实体框架,需要自定义数据库初始化器来放置约束。

相关文章: