国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【EF Core】實(shí)體的主、從關(guān)系

這篇具有很好參考價(jià)值的文章主要介紹了【EF Core】實(shí)體的主、從關(guān)系。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

假設(shè)有以下兩個(gè)實(shí)體:

public class Student
{
    public int StuID { get; set; }
    public string? Name { get; set; }
    public IEnumerable<Homework>? Homeworks { get; set; }
}

public class Homework
{
    public string? Class { get; set; }
    public string? Subject { get; set; }
}

Homework 類表示家庭作業(yè),它并不是獨(dú)立使用的,而是與學(xué)生類(Student)有依賴關(guān)系。一位學(xué)生有多個(gè)家庭作業(yè)記錄,即 Homework 對(duì)象用于記錄每位同學(xué)的作業(yè)的。按照這樣的前提,Student 是主對(duì)象,Homework 是從對(duì)象。

Student 對(duì)象有個(gè) Homeworks 屬性,用于引用 Homework 對(duì)象,也就是所謂的“導(dǎo)航屬性”。這個(gè)“導(dǎo)航”,估計(jì)意思就是你通過(guò)這個(gè)屬性可以找到被引用的另一個(gè)實(shí)體對(duì)象,所以稱之為導(dǎo)航,就是從 Navigation 的翻譯。

隨后,咱們要從 DbContext 類派生出自定義的數(shù)據(jù)庫(kù)上下文。

public class MyDbContext : DbContext
{
    // 映射的數(shù)據(jù)表,名稱默認(rèn)與屬性名稱一樣
    // 即 Students + Works
    public DbSet<Student> Students => Set<Student>();
    public DbSet<Homework> Works => Set<Homework>();

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        // 設(shè)置連接字符串
        optionsBuilder.UseSqlServer(Helper.Conn_STRING);
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // 設(shè)置主鍵
        modelBuilder.Entity<Student>().HasKey(s => s.StuID);
        // 建立主從關(guān)系
        modelBuilder.Entity<Student>().OwnsMany(s => s.Homeworks);
    }
}

連接字符串是老周事先配置好的,連的是 SQL Server。

public class Helper
{
    public const string Conn_STRING = "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=stuDB;Integrated Security=True";
}

用的是 LocalDB,這玩意兒方便。

其實(shí)這是一個(gè)控制臺(tái)應(yīng)用程序,并添加了 Nuget 包。

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.8" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.8" />
  </ItemGroup>

好,回到咱們的代碼中,MyDbContext 重寫(xiě)了兩個(gè)方法:

1、重寫(xiě)?OnConfiguring 方法,做一些與該 Context 有關(guān)的配置,通常是配置連接字符串;也可能配置一下日志輸出。上面代碼中使用的是擴(kuò)展方法?UseSqlServer。這就是引用?Microsoft.EntityFrameworkCore.SqlServer Nuget 包的作用。

2、重寫(xiě)?OnModelCreating 方法。這個(gè)是設(shè)置實(shí)體類相關(guān)的模型屬性,以及與數(shù)據(jù)表的映射,或配置實(shí)體之間的關(guān)系。上述代碼中,老周做了兩件事:A、為 Student 實(shí)體設(shè)置主鍵,作為主鍵的屬性是 StuID;B、建立 Student 和 Homework 對(duì)象的主從關(guān)系,調(diào)用 OwnsMany 方法的意思是:一條 Student 記錄對(duì)應(yīng) N 條 Homework 記錄。因?yàn)?Student 類的 Homeworks 屬性是集合。

在 Main 方法中,咱們要做兩件事:A、根據(jù)上面的建模創(chuàng)建數(shù)據(jù)庫(kù);B、往數(shù)據(jù)庫(kù)中存一點(diǎn)數(shù)據(jù)。

static void Main(string[] args)
{
    using (var ctx = new MyDbContext())
    {
        //ctx.Database.EnsureDeleted();
        bool res = ctx.Database.EnsureCreated();
        if (res)
        {
            Console.WriteLine("已創(chuàng)建數(shù)據(jù)庫(kù)");
        }
    }

    using(MyDbContext ctx = new())
    {
        // 加點(diǎn)料
        ctx.Students.Add(new Student
        {
            Name = "小張",
            Homeworks = new List<Homework>
            {
                new Homework{ Class = "數(shù)學(xué)", Subject = "3000道口算題"},
                new Homework{ Class = "英語(yǔ)", Subject = "背9999個(gè)單詞"}
            }
        });

        ctx.Students.Add(new Student
        {
            Name = "小雪",
            Homeworks = new Homework[]
            {
                new Homework{ Class = "歷史", Subject = "臨一幅《清明上河圖》"},
                new Homework{ Class = "語(yǔ)文", Subject = "作文題:《百鬼日行》"}
            }
        });

        // 保存
        int x = ctx.SaveChanges();
        Console.WriteLine("共保存了{(lán)0}條記錄", x);
    }
}

EnsureCreated 方法會(huì)自動(dòng)創(chuàng)建數(shù)據(jù)庫(kù)。如果不存在數(shù)據(jù)庫(kù)且創(chuàng)建成功,返回 true,否則是 false。數(shù)據(jù)庫(kù)的名稱在連接字符串中配置過(guò)。

Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=stuDB;Integrated Security=True

接下來(lái),我們運(yùn)行一下。稍等幾秒鐘,看到控制臺(tái)輸出下面文本就算成功了。

已創(chuàng)建數(shù)據(jù)庫(kù)
共保存了6條記錄

然后,連上去看看有沒(méi)有數(shù)據(jù)庫(kù)。

【EF Core】實(shí)體的主、從關(guān)系

看看,這表的名稱是不是和 MyDbContext 的兩個(gè)屬性一樣??

public class MyDbContext : DbContext
{
    public DbSet<Student> Students => Set<Student>();
    public DbSet<Homework> Works => Set<Homework>();
    ……

你要是不喜歡用這倆名字,也可以發(fā)動(dòng)傳統(tǒng)技能(指老 EF),用 Table 特性給它們另取高名。

[Table("tb_students", Schema = "dbo")]
public class Student
{
   ……
}

[Table("tb_homeworks", Schema = "dbo")]
public class Homework
{
    ……
}

刪除數(shù)據(jù)庫(kù),再運(yùn)行一次程序,然后再登錄數(shù)據(jù)庫(kù)看看,表名變了嗎?

【EF Core】實(shí)體的主、從關(guān)系

那有伙伴們會(huì)問(wèn):有沒(méi)有現(xiàn)代技能?有的,使用 ToTable 方法定義映射的數(shù)據(jù)表名稱。

先去掉 Student、Homework 類上的 Table 特性,然后直接在重寫(xiě)?OnModelCreating 方法時(shí)配置。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Student>().ToTable("dt_students").HasKey(s => s.StuID);
    modelBuilder.Entity<Homework>().ToTable("dt_works");
    // 建立主從關(guān)系
    modelBuilder.Entity<Student>().OwnsMany(s => s.Homeworks);
}

但是這樣寫(xiě)會(huì)報(bào)錯(cuò)的。因?yàn)?Homework 實(shí)體是 Student 的從屬對(duì)象,單獨(dú)調(diào)用 ToTable 方法在配置的時(shí)候會(huì)將其設(shè)置為獨(dú)立對(duì)象,而非從屬對(duì)象。

所以,正確的做法是在兩個(gè)實(shí)體建立了從屬性關(guān)系后再調(diào)用 ToTable 方法(Student 對(duì)象是主對(duì)象,它可以單獨(dú)調(diào)用)。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Student>().HasKey(s => s.StuID);
    modelBuilder.Entity<Student>()
        .ToTable("tb_students")
        .OwnsMany(s => s.Homeworks)
        .ToTable("tb_works");
}

因?yàn)?Homework 是 Student 的從屬,tb_works 表中要存在一個(gè)外鍵——引用 Student.StuID,這樣兩個(gè)表才能建立主從關(guān)系。如果單獨(dú)調(diào)用 Entity<Homework>.ToTable 映射表的話,那么表中不會(huì)添加引用 StuID 的外鍵列。就是默認(rèn)被配置為非主從模式。沒(méi)有了外鍵,tb_works 表中存的數(shù)據(jù)就無(wú)法知道是哪位學(xué)生的作業(yè)了。

這樣創(chuàng)建數(shù)據(jù)庫(kù)后,tb_works 表中就存在名為 StudentStuID 的列,它就是引用 Student.StuID 的外鍵。

CREATE TABLE [dbo].[tb_works] (
    [StudentStuID] INT            NOT NULL,
    [Id]           INT            IDENTITY (1, 1) NOT NULL,
    [Class]        NVARCHAR (MAX) NULL,
    [Subject]      NVARCHAR (MAX) NULL,
    CONSTRAINT [PK_tb_works] PRIMARY KEY CLUSTERED ([StudentStuID] ASC, [Id] ASC),
    CONSTRAINT [FK_tb_works_tb_students_StudentStuID] FOREIGN KEY ([StudentStuID]) REFERENCES [dbo].[tb_students] ([StuID]) ON DELETE CASCADE
);

當(dāng)然,這個(gè)外鍵名字是根據(jù)實(shí)體類名(Student)和它的主鍵屬性名(StuID)生成的,如果你想自己搞個(gè)名字,也是可以的。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Student>().HasKey(s => s.StuID);
    modelBuilder.Entity<Student>()
        .ToTable("tb_students")
        .OwnsMany(s => s.Homeworks, tb =>
        {
            tb.ToTable("tb_works");
            tb.WithOwner().HasForeignKey("student_id");
        });
}

這樣 tb_works 表中就有了名為 student_id 的外鍵。

CREATE TABLE [dbo].[tb_works] (
    [student_id] INT            NOT NULL,
    [Id]         INT            IDENTITY (1, 1) NOT NULL,
    [Class]      NVARCHAR (MAX) NULL,
    [Subject]    NVARCHAR (MAX) NULL,
    CONSTRAINT [PK_tb_works] PRIMARY KEY CLUSTERED ([student_id] ASC, [Id] ASC),
    CONSTRAINT [FK_tb_works_tb_students_student_id] FOREIGN KEY ([student_id]) REFERENCES [dbo].[tb_students] ([StuID]) ON DELETE CASCADE
);

OwnsXXX 方法是指:俺是主表,我要“關(guān)照”一下從表;

WithOwner 方法是指:俺是從表,我要配置一下和主表之間建立聯(lián)系的參數(shù)(如上面給外鍵另起個(gè)名字)。

那么,我想把兩個(gè)表的列全自定義命名,可以嗎?當(dāng)然可以的。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Student>().HasKey(s => s.StuID);
    modelBuilder.Entity<Student>()
        .ToTable("tb_students", tb =>
        {
            tb.Property(s => s.StuID).HasColumnName("sID");
            tb.Property(s => s.Name).HasColumnName("stu_name");
        })
        .OwnsMany(s => s.Homeworks, tb =>
        {
            tb.ToTable("tb_works");
            tb.WithOwner().HasForeignKey("student_id");
            tb.Property(w => w.Class).HasColumnName("wk_class");
            tb.Property(w => w.Subject).HasColumnName("wk_sub");
        });
}

兩個(gè)表的字段名都變了。

CREATE TABLE [dbo].[tb_students] (
    [sID]      INT            IDENTITY (1, 1) NOT NULL,
    [stu_name] NVARCHAR (MAX) NULL,
    CONSTRAINT [PK_tb_students] PRIMARY KEY CLUSTERED ([sID] ASC)
);

CREATE TABLE [dbo].[tb_works] (
    [student_id] INT            NOT NULL,
    [Id]         INT            IDENTITY (1, 1) NOT NULL,
    [wk_class]   NVARCHAR (MAX) NULL,
    [wk_sub]     NVARCHAR (MAX) NULL,
    CONSTRAINT [PK_tb_works] PRIMARY KEY CLUSTERED ([student_id] ASC, [Id] ASC),
    CONSTRAINT [FK_tb_works_tb_students_student_id] FOREIGN KEY ([student_id]) REFERENCES [dbo].[tb_students] ([sID]) ON DELETE CASCADE
);

注意:Homework 類中沒(méi)有定義 Id 屬性(主鍵),它是自動(dòng)生成的。

?

有大伙伴會(huì)想,在?OnModelCreating 方法中建模我頭有點(diǎn)暈,我能不能在定義實(shí)體類的時(shí)候,直接通過(guò)特性批注來(lái)實(shí)現(xiàn)主從關(guān)系呢?那肯定可以的了。

[Table("tb_students")]
[PrimaryKey(nameof(StuID))]
public class Student
{
    [Column("sID")]
    public int StuID { get; set; }

    [Column("st_name")]
    public string? Name { get; set; }

    // 這是導(dǎo)航屬性,不需要映射到數(shù)據(jù)表
    public IEnumerable<Homework>? Homeworks { get; set; }
}

[Owned]
[Table("tb_homeworks")]
[PrimaryKey(nameof(wID))]
public class Homework
{
    [Column("wk_id")]
    public int wID { get; set; }

    [Column("wk_class")]
    public string? Class { get; set; }

    [Column("wk_sub")]
    public string? Subject { get; set; }

    [ForeignKey("student_id")]  //設(shè)置外鍵名稱
    public Student? StudentObj { get; set; }
}

PrimaryKey 特性設(shè)置實(shí)體類中哪些屬性為主鍵,使用屬性成員的名稱,而不是數(shù)據(jù)表字段名稱。

在 Homework 類上用到?Owned 特性,表示其他對(duì)象如果引用了 Homework,就會(huì)自動(dòng)建立主從關(guān)系—— Homework 為從屬對(duì)象。

ForeignKey 特性指定外鍵的名稱。雖然?StudentObj 屬性的類型是 Student 類,但在建立數(shù)據(jù)表時(shí),只引用了 Student 類的 StuID 屬性。

此時(shí),可以清空?OnModelCreating 方法中的代碼了。

生成的數(shù)據(jù)表結(jié)構(gòu)與上文差不多。

CREATE TABLE [dbo].[tb_students] (
    [sID]     INT            IDENTITY (1, 1) NOT NULL,
    [st_name] NVARCHAR (MAX) NULL,
    CONSTRAINT [PK_tb_students] PRIMARY KEY CLUSTERED ([sID] ASC)
);

CREATE TABLE [dbo].[tb_homeworks] (
    [wk_id]      INT            IDENTITY (1, 1) NOT NULL,
    [wk_class]   NVARCHAR (MAX) NULL,
    [wk_sub]     NVARCHAR (MAX) NULL,
    [student_id] INT            NULL,
    CONSTRAINT [PK_tb_homeworks] PRIMARY KEY CLUSTERED ([wk_id] ASC),
    CONSTRAINT [FK_tb_homeworks_tb_students_student_id] FOREIGN KEY ([student_id]) REFERENCES [dbo].[tb_students] ([sID])
);

當(dāng)然了,最好的做法是將特性批注與?OnModelCreating? 方法結(jié)合使用。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-514743.html

到了這里,關(guān)于【EF Core】實(shí)體的主、從關(guān)系的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • .NET6.0 EF Core 之 DB First生成實(shí)體類

    .NET6.0 EF Core 之 DB First生成實(shí)體類

    EF Core可以使用DB First模式生成實(shí)體類具體步驟如下: 因?yàn)?NET Core中默認(rèn)不包含EF Core的工具和程序包,需要通過(guò)NuGet管理器安裝對(duì)應(yīng)的工具和程序包,這里使用SQL Server數(shù)據(jù)庫(kù)。 Microsoft.EntityFrameworkCore.SqlServer:SQL Server數(shù)據(jù)庫(kù)EF提供程序 Microsoft.EntityFrameworkCore.Design:設(shè)計(jì)時(shí)使用到

    2024年02月06日
    瀏覽(21)
  • .net 6 EF Core MySql數(shù)據(jù)庫(kù)表生成實(shí)體類命令

    安裝下面這幾個(gè)包 Microsoft.EntityFrameworkCore Microsoft.EntityFrameworkCore.Tools Microsoft.EntityFrameworkCore.Design Pomelo.EntityFrameworkCore.MySql Scaffold-DbContext “server=127.0.0.1;port=3306;database=DB;uid=root;pwd=pwdpwd;sslmode=none;” Pomelo.EntityFrameworkCore.MySql -OutputDir Models -Force -NoOnConfiguring -NoPluralize -Context “D

    2024年02月05日
    瀏覽(24)
  • .NET6 + EF Core + MySQL 創(chuàng)建實(shí)體和數(shù)據(jù)庫(kù)、EFCore 數(shù)據(jù)遷移

    .NET6 + EF Core + MySQL 創(chuàng)建實(shí)體和數(shù)據(jù)庫(kù)、EFCore 數(shù)據(jù)遷移

    接上期文章《.NET6項(xiàng)目連接數(shù)據(jù)庫(kù)方式方法》,有人問(wèn)了我?guī)讉€(gè)問(wèn)題,現(xiàn)在就這幾個(gè)問(wèn)題,拓展延申一下創(chuàng)建實(shí)體類、數(shù)據(jù)庫(kù)。把ORM框架和數(shù)據(jù)遷移都寫(xiě)進(jìn)去。 我的項(xiàng)目是在Linux上創(chuàng)建的,使用的是vscode開(kāi)發(fā)工具遠(yuǎn)程開(kāi)發(fā)。為了方便大家閱讀和操作,我將項(xiàng)目down到我的本地電

    2024年02月05日
    瀏覽(23)
  • 記錄一次EF實(shí)體跟蹤錯(cuò)誤

    記錄一次EF實(shí)體跟蹤錯(cuò)誤

    在我寫(xiě)文章編輯接口的,出現(xiàn)了一個(gè)實(shí)體跟蹤的錯(cuò)誤,詳情如下 System.InvalidOperationException: The instance of entity type \\\'Tag\\\' cannot be tracked because another instance with the same key value for {\\\'Id\\\'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attach

    2024年02月11日
    瀏覽(20)
  • 使用EF6(DB First模式)無(wú)法生成對(duì)應(yīng)模型實(shí)體類

    使用EF6(DB First模式)無(wú)法生成對(duì)應(yīng)模型實(shí)體類

    最近升級(jí)了,Visual Stidio 2022,在使用EF6時(shí)(DB First模式),無(wú)法生成對(duì)應(yīng)模型的實(shí)體類,如下: ?對(duì)于該問(wèn)題,我去微軟社區(qū),找到了兩個(gè)解決方案: 1.從 Visual Studio2022 16.x 版本回滾到 Visual Studio2022 15.x 版本即可解決問(wèn)題; 2.修改EF6的實(shí)用程序.CS.ttinclude,它默認(rèn)的位置在:C:Program FilesMicro

    2024年02月11日
    瀏覽(21)
  • 4.1EF Core

    EF Core是微軟官方的ORM框架,ORM即對(duì)象關(guān)系映射,也就是我們可以直接操作C#中的對(duì)象就可以完成數(shù)據(jù)庫(kù)的操作。 EF Core環(huán)境搭建 首先要?jiǎng)?chuàng)建C#對(duì)象,用以對(duì)應(yīng)數(shù)據(jù)庫(kù)中的表,該C#對(duì)象也成為實(shí)體類。 根據(jù)所用的數(shù)據(jù)庫(kù)選擇NuGet包,本文使用SQLite數(shù)據(jù)庫(kù),所以安裝Microsoft.EntityF

    2024年02月05日
    瀏覽(18)
  • EF Core入門

    EF Core入門

    EF Core是微軟官方提供的ORM框架。EF Core不僅可以操作Microsoft SQL Server、MySQL、Oracle、PostgreSQL等數(shù)據(jù)庫(kù),而且可以操作Azure Cosmos DB等NoSQL數(shù)據(jù)庫(kù) 前提條件:已經(jīng)完整安裝了Microsoft SQL Server 下面是一個(gè)實(shí)際操作EF Core的演示 這是項(xiàng)目最終的目錄,這里需要關(guān)注的就是 .cs 文件 首先新

    2023年04月09日
    瀏覽(18)
  • EF Core并發(fā)控制

    EF Core并發(fā)控制

    并發(fā)控制:避免多個(gè)用戶同時(shí)操作資源造成的并發(fā)沖突問(wèn)題。 最好的解決方案:非數(shù)據(jù)庫(kù)解決方案 數(shù)據(jù)庫(kù)層面的兩種策略:悲觀、樂(lè)觀 悲觀并發(fā)控制一般采用行鎖 ,表鎖等排他鎖對(duì)資源進(jìn)行鎖定,確保同時(shí)只有一個(gè)使用者操作被鎖定的資源。 EF Core沒(méi)有封裝悲觀并發(fā)控制的

    2024年02月10日
    瀏覽(20)
  • Net Core中使用EF Core連接Mysql數(shù)據(jù)庫(kù)

    Net Core中使用EF Core連接Mysql數(shù)據(jù)庫(kù)

    Entity Framework Core的前身是微軟提供并主推的ORM框架,簡(jiǎn)稱EF,其底層是對(duì)ADO.NET的封裝。EF支持SQLServer、MYSQL、Oracle、Sqlite等所有主流數(shù)據(jù)庫(kù)。 首先是使用時(shí)的幾個(gè)模式的整理及其理解: Code First:根據(jù)代碼自動(dòng)創(chuàng)建數(shù)據(jù)庫(kù)表結(jié)構(gòu)甚至是數(shù)據(jù)庫(kù),可以支持多庫(kù)開(kāi)發(fā),代碼較少冗余

    2024年01月24日
    瀏覽(28)
  • 使用EF Core創(chuàng)建webapi接口(二)

    使用EF Core創(chuàng)建webapi接口(二)

    有錯(cuò)誤歡迎大家給我指正 說(shuō)明:netcore webapi+net6+EF?Core版本,codefirst模式(代碼創(chuàng)建數(shù)據(jù)庫(kù)) 1.netcore webapi+net6+EF?Core版本,dbfirst模式(代碼生成數(shù)據(jù)庫(kù))見(jiàn):使用EF Core創(chuàng)建webapi接口(一)-CSDN博客 2.netcore webapi+net6+EF?Core+vue前后端聯(lián)動(dòng)版本,見(jiàn)netcore webapi+net6+EF Core+vue3前后端聯(lián)動(dòng)-CSD

    2024年02月21日
    瀏覽(25)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包