简体   繁体   English

首先通过代码发布一对多关系

[英]Issue with 1 to many relationship through code first

I just asked question and got the solution also, but the solution creates a new issue which i am mentioning here. 我只是问了一个问题 ,也得到了解决方案,但是该解决方案创建了一个新问题,我在这里提到。 Here i modify my code and creates a new 1 to 1 relation between AccountHolder and Nominee . 在这里,我修改了代码,并在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; }
}

The relationship between them are as follows : 它们之间的关系如下:

  1 to many between AccountHolder and Address
  1 to many between Nominee and Address
  1 to 1 between AccountHolder and Nominee

The fluent Api code for this is : 流畅的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();

Firstly if there is any scope of improvement than please suggest me. 首先,如果有任何改进的余地,请提出建议。 Now the problem which i am facing here is whenever i insert AccountHolder i have to create a empty instance of Nominee and while inserting Nominee i have to create empty instance of AccountHolder . 现在我面临的问题是,每当我插入AccountHolder我必须创建一个Nominee的空实例,而在插入Nominee我必须创建一个AccountHolder空实例。 And if i will not do this than the error occurred which i have mentioned on my previous question. 而且,如果我不这样做,那么会发生我在上一个问题中提到的错误。 Can anybody please guid me how i can solve this issue, please add the example code in your solution. 谁能指导我如何解决此问题,请在您的解决方案中添加示例代码。

Code i am using for inserting data is : 我用于插入数据的代码是:

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

Thanks! 谢谢!

Ok finally i got the solution, but if there a better solution than please suggest me. 好的,终于我找到了解决方案,但是如果有比它更好的解决方案,请提出建议。 What i did is create the FKs in Address table optional (nullable) : 我所做的是在地址表可选(可空)中创建FK:

Change in classes : 班次变更:

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

change in fluent api : 流利的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();

as far as I understant your needs, the following runs. 据我对您的需求的了解,可以执行以下操作。

Note that setting the AccountHolderId is a bit hard because, with the one to one relation with nominee, the PK of Nominee is also a FK. 请注意,设置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();
        }
    }    
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM