<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      劉凱的博客

      導航

      Entity Framework Code First 學習日記(8)-一對一關系

      通過上面兩篇日記,我相信大家已經知道了Entity Framework Code First如何根據類之間的依賴關系推斷并建立數據庫中表之間的一對多和多對多關系。這次日記我們將詳細Entity Framework Code First是如何建立數據庫中的一對一關系。

      在介紹一對多關系和多對多關系時,大家應該已經注意到了只要存在依賴關系的兩個類的定義中包含對方的實例或實例的集合,Entity Framework Code First會自動推斷出與之對應的數據庫關系。這個方式對一對一關系也同樣適用嗎?先讓我們來作一個實驗。

      假設我們的訂單系統現在需要存儲每個客戶的銀行賬號信息。顯然,在我們的訂單系統中,銀行賬號并不是我們關注的重點,我只需要保存賬號的號碼,開戶行以及賬號名稱,由此可見銀行賬號在我們這里只是一個值對象。

      我們需要定義銀行賬號類:

      public class BankAccount
          {
              public string AccountNumber { get; set; }
              public DateTime CreatedDate { get; set; }
              public string BankName { get; set; }
              public string AccountName { get; set; }
          }

      我們還需要在客戶類當中包含一個銀行賬號類的實例。

       

      public class Customer
          {
              public string IDCardNumber { get; set; }
              public string CustomerName { get; set; }
              public string Gender { get; set; }
              public Address Address { get; set; }
              public string PhoneNumber { get; set; }
              public BankAccount Account { get; set; }
          }

      我們寫一個單元測試程序,看看Entity Framework Code First會不是自動地根據兩個類的依賴關系創建數據庫中的一對一關系。

       

      [TestMethod]
              public void CanAddCustomerWithBankAccount()
              {
                  OrderSystemContext unitOfWork = new OrderSystemContext();
                  CustomerRepository repository = new CustomerRepository(unitOfWork);
                  Customer newCustomer = new Customer() { IDCardNumber = "120104198106072518", CustomerName = "Alex", Gender = "M", PhoneNumber = "test" };
                  Address customerAddress = new Address { Country = "China", Province = "Tianjin", City = "Tianjin", StreetAddress = "Crown Plaza", ZipCode = "300308" };
                  BankAccount account = new BankAccount { AccountNumber = "2012001001", BankName = "ICBC", AccountName = "Alex", CreatedDate = DateTime.Parse("2012-1-21") };
                  newCustomer.Address = customerAddress;
                  newCustomer.Account = account;
                  repository.AddNewCustomer(newCustomer);
                  unitOfWork.CommitChanges();
              }

       

      我們運行一下我們的單元測試程序,程序會拋出異常:

      Test method EntityFramework.CodeFirst.Demo1.UnitTest.CustomerRepositoryUnitTest.CanAddCustomerWithBankAccount threw exception: 
      System.Data.DataException: An exception occurred while initializing the database. See the InnerException for details. ---> System.Data.Entity.Infrastructure.DbUpdateException: Null value for non-nullable member. Member: 'Account'. ---> System.Data.UpdateException: Null value for non-nullable member. Member: 'Account'.

       

      這是為什么呢?因為Entity Framework Code First無法根據類之間的依賴關系推斷并建立一對一關系,它根本搞不清楚在這兩個存在依賴關系的類中,哪個是主表,哪個是子表,外鍵應該建立在哪個表中。一對多關系中非常容易分清主表和子表,哪個類中包含另一個的實例集合,它就是主表。多對多關系是通過連接表建立的,不需要分清主表和子表。但是到一對一關系時,這就是個問題了。

      要想讓Entity Framework Code First根據類之間的依賴關系推斷并建立一對一關系,你必須幫助它,告訴他哪個是主表,哪個是子表。

      假設一個銀行賬號必須有對應的客戶,但是客戶可以沒有銀行賬號,并且由于銀行賬號是個值對象,沒有必要讓它包含客戶類的實例。

      因為銀行賬號類的定義中并不包含客戶類的實例,所以我們需要在客戶類的配置方法中設定這個一對一關系。

      public class CustomerEntityConfiguration:EntityTypeConfiguration<Customer>
          {
              public CustomerEntityConfiguration()
              {
                  HasKey(c => c.IDCardNumber).Property(c => c.IDCardNumber).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
                  this.Property(c => c.IDCardNumber).HasMaxLength(20);
                  this.Property(c => c.CustomerName).IsRequired().HasMaxLength(50);
                  this.Property(c => c.Gender).IsRequired().HasMaxLength(1);
                  this.Property(c => c.PhoneNumber).HasMaxLength(20);
                  this.HasOptional(c => c.Account).WithOptionalDependent();
              }
          }

      在客戶類中的HasOptional意味著客戶類可以有也可以沒有銀行賬號。當我們通過HasOptional指定Customer與BankAccount類的關系時,Entity Framework Code First要求我們指定它們之間的依賴關系。這時,IntelliSense會讓你在兩個方法之間進行選擇:WithOptionalDependent和WithOptionalPrincipal。如果你選擇WithOptionalDependent則代表Customer表中有一個外鍵指向BankAccount表的主鍵,如果你選擇WithOptionalPrincipal則相反,BankAccount擁有指向Customer表的外鍵。

      執行一下我們的單元測試,這次就不會報錯了。然后我們打開SQL Server,我們發現Entity Framework Code First映射到正確的一對一關系。

      image

       

      大家可以看到Customer表中的外鍵是可以為空的,這是由于我們使用了HasOptional。如果我們需要一對一關系中的外鍵不能為空,我們就需要使用HasRequired.

      HasRequired(c => c.Account).WithRequiredDependent();

      當我們使用HasRequired時候,IntelliSense會讓你在WithRequiredDependent和WithRequiredPrinciple之間選擇, 這里的dependent和principle也是用于決定主鍵在哪個表的。

      但是有一點非常奇怪,我使用的Entity Framework版本是4.1,當我執行我的測試程序時,我發現一個非常奇怪的事情。Code First并不是按照HasOptional的那樣建立一個外鍵,而是把Customer的主鍵同時變為指向BankAccount表的外鍵:

      image

       

      這肯定不是我們希望的結果,因為Code First會把AccountNumber當成IDCardNumber存進去。我覺得這可能是EF4.1中的一個bug。

      但是我們可以通過我們前面學過的指定外鍵名稱的方法來定義正確的外鍵。

      HasRequired(c => c.Account).WithRequiredDependent().Map(c => c.MapKey("AccountId")); 

      我們再次執行我們的測試程序得到的就是正確的結果了:

      image

       

      由于我在前面兩篇日記中已經介紹了級聯刪除以及更改外鍵名稱的方法,我在這篇日記中就不再重復了。我們下一篇的日記將探討如何將類之間的繼承關系映射到數據庫中去。

      posted on 2013-01-22 11:02  劉凱  閱讀(5030)  評論(3)    收藏  舉報

      主站蜘蛛池模板: 国产熟女激情一区二区三区| 他掀开裙子把舌头伸进去添视频 | 美女午夜福利视频一区二区| 精品熟女日韩中文十区| 中文字幕人妻无码一夲道| 国产一区二区三区麻豆视频| 日韩深夜免费在线观看| 一边吃奶一边摸做爽视频| 日韩福利片午夜免费观着| 国产亚洲无线码一区二区| 中文字幕在线日韩| 亚洲精品电影院| 国产蜜臀久久av一区二区| 鲁丝片一区二区三区免费| 亚洲欧美综合中文| 99久久国产综合精品色| 国产真实乱对白精彩久久老熟妇女 | 国产精品国产三级国产试看 | 欧美不卡无线在线一二三区观| 热99久久这里只有精品| 国产成人午夜福利院| 三江| 免费午夜无码片在线观看影院| 中文字幕国产精品综合| 美女胸18大禁视频网站| 色悠悠久久精品综合视频 | 亚洲熟女片嫩草影院| 霍山县| 激情五月开心综合亚洲| 欧洲精品码一区二区三区| 高潮射精日本韩国在线播放| 国产精品一区中文字幕| 人妻体内射精一区二区三区| 久热这里只国产精品视频| 亚洲一区二区三区啪啪| 亚洲乱码中文字幕久久孕妇黑人| 人妻少妇精品系列一区二区| 国产午夜精品亚洲精品国产| 国产在线观看91精品亚瑟| 大又大又粗又硬又爽少妇毛片| 久青草视频在线观看免费|