首先通过代码解决1对多关系的问题

本文关键字:关系 问题 解决 代码 | 更新日期: 2023-09-27 18:02:12

我只是问了问题,也得到了解决方案,但解决方案产生了一个新的问题,我在这里提到。在这里,我修改了我的代码,并在AccountHolderNominee之间创建了一个新的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
                             } 
                          } 
                       } 
};

谢谢!

首先通过代码解决1对多关系的问题

好了,我终于有了解决方案,但如果有更好的解决方案,请建议我。我所做的是在地址表可选(可空)中创建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();
        }
    }    
}