首先通过代码解决1对多关系的问题
本文关键字:关系 问题 解决 代码 | 更新日期: 2023-09-27 18:02:12
我只是问了问题,也得到了解决方案,但解决方案产生了一个新的问题,我在这里提到。在这里,我修改了我的代码,并在AccountHolder
和Nominee
之间创建了一个新的1对1关系。
public partial class AccountHolder
{
public int AccountHolderId { get; set; }
public virtual List<Address> Address { get; set; }
public virtual Nominee Nominee { get; set; }
}
public partial class Nominee
{
public int NomineeId { get; set; }
public virtual List<Address> Address { get; set; }
}
public partial class Address
{
public int AddressId { get; set; }
public int AccountHolderId { get; set; }
public AccountHolder AccountHolder { get; set; }
public int NomineeId { get; set; }
public Nominee Nominee { get; set; }
}
它们之间的关系如下:
1 to many between AccountHolder and Address
1 to many between Nominee and Address
1 to 1 between AccountHolder and Nominee
这个流畅的Api代码是:
modelBuilder.Entity<AccountHolder>().HasOptional(p => p.Nominee)
.WithRequired()
.WillCascadeOnDelete(false);
modelBuilder.Entity<Address>().HasRequired(p => p.AccountHolder)
.WithMany(p => p.Address)
.HasForeignKey(p => p.AccountHolderId)
.WillCascadeOnDelete();
modelBuilder.Entity<Address>().HasRequired(p => p.Nominee)
.WithMany(p => p.Address)
.HasForeignKey(p => p.NomineeId)
.WillCascadeOnDelete();
首先,如果有任何改进的范围,请建议我。现在我在这里面临的问题是,每当我插入AccountHolder
时,我必须创建Nominee
的空实例,而插入Nominee
时,我必须创建AccountHolder
的空实例。如果我不这样做,就会出现我在上一个问题上提到的错误。有没有人能告诉我如何解决这个问题,请在您的解决方案中添加示例代码。
我用来插入数据的代码是:
var accountHolder = new AccountHolder() {
AccountHolderId = 901,
Address = new List<Address>()
{
new Address()
{
HouseNumber = hnumber,
Street = street,
Nominee = new Nominee() //this is the issue
}
},
Nominee = new Nominee()
{
Address = new List<Address>()
{
new Address()
{
HouseNumber = n_hnumber,
Street = n_street,
AccountHolder = new AccountHolder() //this is the issue
}
}
}
};
谢谢!
好了,我终于有了解决方案,但如果有更好的解决方案,请建议我。我所做的是在地址表可选(可空)中创建fk:
类的变化:
public partial class Address
{
public int AddressId { get; set; }
public int? AccountHolderId { get; set; }
public AccountHolder AccountHolder { get; set; }
public int? NomineeId { get; set; }
public Nominee Nominee { get; set; }
}
在fluent API中的变化:
modelBuilder.Entity<AccountHolder>().HasOptional(p => p.Nominee)
.WithRequired()
.WillCascadeOnDelete(false);
modelBuilder.Entity<Address>().HasOptional(p => p.AccountHolder)
.WithMany(p => p.Address)
.HasForeignKey(p => p.AccountHolderId)
.WillCascadeOnDelete();
modelBuilder.Entity<Address>().HasOptional(p => p.Nominee)
.WithMany(p => p.Address)
.HasForeignKey(p => p.NomineeId)
.WillCascadeOnDelete();
据我所知,您的需求如下:
请注意,设置AccountHolderId有点困难,因为与提名人的一对一关系,提名人的PK也是FK。
using System;
using System.Linq;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
namespace testEF {
class Program {
static void Main(string[] args) {
using ( EFContext efc = new EFContext() ) {
var AHAddress = new Address {
AddressId = 1,
HouseNumber = "150",
Street = "street",
};
var AHNominee = new Nominee {
NomineeId = 1,
Address = new List<Address>() {
AHAddress
}};
var accountHolder = new AccountHolder() {
Address = new List<Address>() {
AHAddress
},
Nominee = AHNominee
};
efc.Holders.Add(accountHolder);
efc.SaveChanges();
foreach (AccountHolder ah in efc.Holders) {
Console.WriteLine("{0} -> {1}", ah.AccountHolderId, ah.Nominee.NomineeId);
}
};
}
}
public partial class AccountHolder {
public int AccountHolderId { get; set; }
public virtual List<Address> Address { get; set; }
public virtual Nominee Nominee { get; set; }
}
public partial class Nominee {
public int NomineeId { get; set; }
public virtual List<Address> Address { get; set; }
}
public partial class Address {
public int AddressId { get; set; }
public String HouseNumber { get; set; }
public String Street { get; set; }
public int AccountHolderId { get; set; }
public AccountHolder AccountHolder { get; set; }
public int NomineeId { get; set; }
public Nominee Nominee { get; set; }
}
public class EFContext : DbContext {
public IDbSet<AccountHolder> Holders { get; set; }
public EFContext()
: base() {
Database.SetInitializer<EFContext>(new DropCreateDatabaseAlways<EFContext>());
}
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<AccountHolder>().HasOptional(p => p.Nominee)
.WithRequired()
.WillCascadeOnDelete(false);
modelBuilder.Entity<Address>().HasRequired(p => p.AccountHolder)
.WithMany(p => p.Address)
.HasForeignKey(p => p.AccountHolderId)
.WillCascadeOnDelete();
modelBuilder.Entity<Address>().HasRequired(p => p.Nominee)
.WithMany(p => p.Address)
.HasForeignKey(p => p.NomineeId)
.WillCascadeOnDelete();
}
}
}