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

时间:2013-03-03 15:19:09

标签: c# sql code-first

我刚刚问了question并得到了解决方案,但解决方案创建了一个我在这里提到的新问题。在这里,我修改了我的代码,并在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
                             } 
                          } 
                       } 
};

谢谢!

2 个答案:

答案 0 :(得分:0)

好的,最后我得到了解决方案,但如果有更好的解决方案,请建议我。我所做的是在地址表中创建FKs可选(可为空):

课程变更:

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

流畅的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();

答案 1 :(得分:-1)

就我理解你的需求而言,以下运行。

请注意,设置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();
        }
    }    
}