EF實體框架之CodeFirst五


上一博客學習了下基本的約定配置,留下幾個遺漏的,這篇就是學習下遺漏一復雜類型。

一、什么是復雜類型?

書中說道:“復雜類型也可視作值類型(?)可以作為附加屬性添加到其他類。復雜類型與實體類型的區別在於復雜類型沒有其自己的鍵。它是依賴於其"宿主"類型跟蹤變化 和持久化。一個沒有Key屬性的類型,並且作為屬性映射到一個或多個類型中,Code First就會將其視作為復雜類型。Code First將預設復雜類型的屬性出現在宿主類型映射到數據庫的表中。”

說簡單一點就是,項目中有個類A,這個A,會被其他類引用到比如:實體類B 和 實體類C,但是建立數據庫的時候,我們不想為這個分割類A建立表,而是把A類中的屬性等建立到 B 和 C 映射的表中,這時候,我們管 A 叫做復雜類型。

二、復雜類型和實體類型的區別

首先還是定義兩個類Person類和IDCard類還有數據庫上下文。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;
using EFCodeFirstModels;
using System.Configuration;


namespace EFCodeFirstDataAccess
{
    public class EFCodeFirstDbContext:DbContext
    {

        public EFCodeFirstDbContext() : base("MyStrConn")
        {
        }
        public DbSet<Person> Persons { get; set; }
    }
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EFCodeFirstModels
{
    public enum SexType { Male, Female }

    [Table("Person")]
    public class Person
    {
        [Key]
        public string PersonId { get; set; }
        //姓名
      
        public string Name { get; set; }
        //性別
        public SexType Sex { get; set; }
        //年齡
        public int Age { get; set; }

        public IDCard Card { get; set; }


        public Person(string personId, string name, SexType sex, int age,IDCard card)
        {
            PersonId = personId;
            Name = name;
            Sex = sex;
            Age = age;
            Card = card;
         
        }
        public Person() { }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace EFCodeFirstModels
{
    
    public class IDCard
    {
        //法定出生日期
        public DateTime BirthDate { get; set; }

    }
}

在上面的IDCard中並沒有主鍵,這個是需要留意的,然后呢新增一個Person對象在數據庫上下文中。

            using (var db=new EFCodeFirstDbContext())
            {
                IDCard card = new IDCard();
                card.BirthDate = DateTime.Now;
                Person p = new Person("0001","cuiyanwei",SexType.Female,25,card);
                db.Persons.Add(p);
                db.SaveChanges();
                Console.WriteLine("Scueess");
            }

此時會生成下面的表結構。

上面可以看到Person表中增加了一個Card_BirthDate列,但是如果在IDCard類中增加一個主鍵,結果就會不一樣。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace EFCodeFirstModels
{
    
    public class IDCard
    {
        [Key]
        public int CardId { get; set; }
        //法定出生日期
        public DateTime BirthDate { get; set; }

    }
}

可以看到,數據庫中多生成了一個表。Person表中增加了一個外鍵Card_CardId.

三、復雜類型嵌套

看到這你可能會問這也沒提到復雜類型幾個字啊,哪來的復雜類型了。上面的例子中IDCard雖然也是復雜類型,由於IDCard類中屬性比較簡單,沒有嵌套這其他的類,所以EF就默認映射到Person表中了,但是假如IDCard類中有其他的類,屬於類型嵌套的話那就麻煩了。首先看下如果有嵌套不指定會怎么樣?

可以在IDCard類中增加一個屬性,用來表示出生地方的經緯度(做個比喻,不可能人出生在一個經緯度的點上,也是大致的位置)。經緯度用Location類表示。

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EFCodeFirstModels
{
    //[ComplexType]
    public class Location
    {
        //經度
        public double Longitude { get; set; }

        //緯度
        public double Latitude { get; set; }

    }
}
    public class IDCard
    {

        //法定出生日期
        public DateTime BirthDate { get; set; }

        //出生地的位置 經緯度
        public Location BirthPlace { get; set; }

    }

同樣新增一個Person對象,此時就會報下面的錯誤。

這是為什么呢?因為系統識別不了IDCard類是復雜類型。那怎么解決呢,很簡單。只需指定IDCard是復雜類型就ok了。

    [ComplexType]
    public class IDCard

而在Location類上並沒有指定復雜類型,這也將Location類認為是復雜類型。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM