最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Entity?Framework?Core關(guān)聯(lián)刪除

 更新時間:2021年12月29日 17:05:00   作者:Sweet?Tang  
關(guān)聯(lián)刪除通常是一個數(shù)據(jù)庫術(shù)語,用于描述在刪除行時允許自動觸發(fā)刪除關(guān)聯(lián)行的特征;即當(dāng)主表的數(shù)據(jù)行被刪除時,自動將關(guān)聯(lián)表中依賴的數(shù)據(jù)行進(jìn)行刪除,或者將外鍵更新為NULL或默認(rèn)值。本文將為大家具體介紹一下Entity?Framework?Core關(guān)聯(lián)刪除,需要的可以參考一下

關(guān)聯(lián)刪除通常是一個數(shù)據(jù)庫術(shù)語,用于描述在刪除行時允許自動觸發(fā)刪除關(guān)聯(lián)行的特征;即當(dāng)主表的數(shù)據(jù)行被刪除時,自動將關(guān)聯(lián)表中依賴的數(shù)據(jù)行進(jìn)行刪除,或者將外鍵更新為NULL或默認(rèn)值。

數(shù)據(jù)庫關(guān)聯(lián)刪除行為

我們先來看一看SQL Server中支持的行為。在創(chuàng)建外鍵約束時,可以指定關(guān)聯(lián)表在主表刪除行時,對依賴的數(shù)據(jù)如何執(zhí)行操作。例如下面的SQL語句,[Order Details]表中[OrderID]字段 是外鍵,依賴于[Orders]表中的主鍵[OrderID]。

CREATE TABLE [Orders] (
    [OrderID] int NOT NULL IDENTITY,
    [Name] nvarchar(max) NULL,
    [OrderDate] datetime2 NULL,
    CONSTRAINT [PK_Orders] PRIMARY KEY ([OrderID])
);

GO

CREATE TABLE [Order Details] (
    [DetailId] int NOT NULL IDENTITY,
    [OrderID] int NULL,
    [ProductID] int NOT NULL,
    CONSTRAINT [PK_Order Details] PRIMARY KEY ([DetailId]),
    CONSTRAINT [FK_Order Details_Orders_OrderID] FOREIGN KEY ([OrderID]) REFERENCES [Orders] ([OrderID]) ON DELETE SET NULL
);

外鍵約束[FK_Order Details_Orders_OrderID]末尾的語句是ON DELETE SET NULL,表示當(dāng)主表的數(shù)據(jù)行刪除時,自動將關(guān)聯(lián)表數(shù)據(jù)行的外鍵更新為NULL。

在SQL Server中支持如下四種行為:

1.ON DELETE NO ACTION

默認(rèn)行為,刪除主表數(shù)據(jù)行時,依賴表中的數(shù)據(jù)不會執(zhí)行任何操作,此時會產(chǎn)生錯誤,并回滾DELETE語句。例如會產(chǎn)生下面的錯誤:

DELETE 語句與 REFERENCE 約束"FK_Order Details_Orders_OrderID"沖突。該沖突發(fā)生于數(shù)據(jù)庫"Northwind_Test",表"dbo.Order Details", column 'OrderID'。

語句已終止。

2.ON DELETE CASCADE

刪除主表數(shù)據(jù)行時,依賴表的中數(shù)據(jù)行也會同步刪除。

3.ON DELETE SET NULL

刪除主表數(shù)據(jù)行時,將依賴表中數(shù)據(jù)行的外鍵更新為NULL。為了滿足此約束,目標(biāo)表的外鍵列必須可為空值。

4.ON DELETE SET DEFAULT

刪除主表數(shù)據(jù)行時,將依賴表的中數(shù)據(jù)行的外鍵更新為默認(rèn)值。為了滿足此約束,目標(biāo)表的所有外鍵列必須具有默認(rèn)值定義;如果外鍵可為空值,并且未顯式設(shè)置默認(rèn)值,則將使用NULL作為該列的隱式默認(rèn)值。

簡單介紹了數(shù)據(jù)庫中行為后,我們來著重介紹 EF Core 中的關(guān)聯(lián)實體的行為。

定義實體

我們先定義兩個實體Order、OrderDetail分別表示訂單和訂單明細(xì);其中Order與OrderDetail的關(guān)系是一對多,在OrderDetail實體中OrderID表示外鍵,依賴于Order實體中的主鍵OrderID。

    public class Order
    {
        public int OrderID { get; set; }

        public string Name { get; set; }

        public DateTime? OrderDate { get; set; }

        public ICollection<OrderDetail> OrderDetails { get; set; }
    }

    public class OrderDetail
    {
        public int DetailId { get; set; }

        public int? OrderID { get; set; }
        
        public int ProductID { get; set; }

        public Order Order { get; set; }
    }

Fluent API 配置關(guān)聯(lián)實體

在DbContext中OnModelCreating方法中,我們使用 Fluent API 配置實體中之間的關(guān)系。

    public class NorthwindContext : DbContext
    {

        public virtual DbSet<Order> Orders { get; set; }
        public virtual DbSet<OrderDetail> OrderDetails { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Order>(
                builder =>
                {
                    builder.HasMany<OrderDetail>(e => e.OrderDetails).WithOne(e => e.Order).HasForeignKey(e => e.OrderID).OnDelete(DeleteBehavior.ClientSetNull);
                });
        }
    }

在OnDelete方法中,需要傳遞參數(shù)DeleteBehavior枚舉,分別有如下四個值:

    public enum DeleteBehavior
    {
        Cascade,

        SetNull,

        ClientSetNull,

        Restrict
    }    

這四個枚舉值的分別表示不同的行為,這也是我們今天的重點。

創(chuàng)建表結(jié)構(gòu)

我們分別使用使用這這個枚舉值,來創(chuàng)建數(shù)據(jù)表結(jié)構(gòu)。

        [InlineData(DeleteBehavior.Cascade)]
        [InlineData(DeleteBehavior.SetNull)] 
        [InlineData(DeleteBehavior.ClientSetNull)]
        [InlineData(DeleteBehavior.Restrict)]
        [Theory]
        public void Create_Database(DeleteBehavior behavior)
        {
            using (var northwindContext = new NorthwindContext(behavior))
            {
                northwindContext.Database.EnsureDeleted();
                northwindContext.Database.EnsureCreated();
            }
        }
        

四個枚舉值創(chuàng)建表的SQL語句類似如下,唯一區(qū)別在于創(chuàng)建外鍵約束[FK_Order Details_Orders_OrderID]中ON DELETE {}后面的語句。

CREATE TABLE [Orders] (
    [OrderID] int NOT NULL IDENTITY,
    [Name] nvarchar(max) NULL,
    [OrderDate] datetime2 NULL,
    CONSTRAINT [PK_Orders] PRIMARY KEY ([OrderID])
);

GO

CREATE TABLE [Order Details] (
    [DetailId] int NOT NULL IDENTITY,
    [OrderID] int NOT NULL,
    [ProductID] int NOT NULL,
    CONSTRAINT [PK_Order Details] PRIMARY KEY ([DetailId]),
    CONSTRAINT [FK_Order Details_Orders_OrderID] FOREIGN KEY ([OrderID]) REFERENCES [Orders] ([OrderID]) ON DELETE CASCADE
);

四個枚舉值分別對應(yīng)的SQL語句如下:

EF Core 關(guān)聯(lián)實體刪除行為

我們分別通過枚舉值與是否跟蹤關(guān)聯(lián)實體,進(jìn)行代碼測試,測試代碼如下:

        [InlineData(DeleteBehavior.Cascade, true)]
        [InlineData(DeleteBehavior.Cascade, false)]
        [InlineData(DeleteBehavior.SetNull, true)]
        [InlineData(DeleteBehavior.SetNull, false)]
        [InlineData(DeleteBehavior.ClientSetNull, true)]
        [InlineData(DeleteBehavior.ClientSetNull, false)]
        [InlineData(DeleteBehavior.Restrict, true)]
        [InlineData(DeleteBehavior.Restrict, false)]

        [Theory]
        public void Execute(DeleteBehavior behavior, bool includeDetail)
        {
            using (var northwindContext = new NorthwindContext(behavior))
            {
                northwindContext.Database.EnsureDeleted();
                northwindContext.Database.EnsureCreated();
            }

            int orderId;
            int detailId;
            using (var northwindContext = new NorthwindContext(behavior))
            {
                var order = new Order {
                    Name = "Order1"
                };

                var orderDetail = new OrderDetail {
                    ProductID = 11
                };
                order.OrderDetails = new List<OrderDetail> {
                    orderDetail
                };


                northwindContext.Set<Order>().Add(order);
                                northwindContext.SaveChanges();

                orderId = order.OrderID;
                detailId = orderDetail.DetailId;
            }

            using (var northwindContext = new NorthwindContext(behavior))
            {
                var queryable = northwindContext.Set<Order>().Where(e => e.OrderID == orderId);
                if (includeDetail){
                    queryable = queryable.Include(e => e.OrderDetails);
                }

                var order = queryable.Single(); 
                northwindContext.Set<Order>().Remove(order);

                try
                {
                    northwindContext.SaveChanges();
                    DumpSql();
                }
                catch (Exception)
                {
                    DumpSql();
                    throw;
                }

            }

            using (var northwindContext = new NorthwindContext(behavior))
            {
                var orderDetail = northwindContext.Set<OrderDetail>().Find(detailId);
                if (behavior == DeleteBehavior.Cascade)
                {
                    Assert.Null(orderDetail);
                }
                else
                {
                    Assert.NotNull(orderDetail);
                }
            }
        }
        ?

? ? ? ??

總結(jié)

根據(jù)上面的測試結(jié)果,我們可以出得如下結(jié)論:

DeleteBehavior.Cascade

  • 如果關(guān)聯(lián)實體未被跟蹤,主實體的狀態(tài)標(biāo)記為刪除,執(zhí)行SaveChage時,在刪除主表的數(shù)據(jù)的同時,通過數(shù)據(jù)庫的行為刪除關(guān)聯(lián)表的數(shù)據(jù)行;
  • 如果關(guān)聯(lián)實體已經(jīng)被跟蹤,將主實體的狀態(tài)標(biāo)記為刪除時,關(guān)聯(lián)實體的狀態(tài)也會標(biāo)記為刪除,執(zhí)行SaveChange時,先刪除關(guān)聯(lián)表的數(shù)據(jù)行,然后再刪除主表的數(shù)據(jù)行;
  • 外鍵可以設(shè)置非空值、也可以設(shè)置為可為空值;
  • 關(guān)聯(lián)實體可以不被跟蹤。

DeleteBehavior.SetNull

  • 如果關(guān)聯(lián)實體未被跟蹤,主實體的狀態(tài)標(biāo)記為刪除,執(zhí)行SaveChage時,在刪除主表的數(shù)據(jù)時,通過數(shù)據(jù)庫的行為將關(guān)聯(lián)表數(shù)據(jù)行的外鍵更新為NULL,;
  • 如果關(guān)聯(lián)實體已經(jīng)被跟蹤,將主實體的狀態(tài)標(biāo)記為刪除時,關(guān)聯(lián)實體的外鍵會被設(shè)置為null,同時將關(guān)聯(lián)實體的狀態(tài)標(biāo)記為修改,執(zhí)行SaveChange時,先更新關(guān)聯(lián)表的數(shù)據(jù)行 ,然后刪除主表的數(shù)據(jù)行;
  • 因為要將外鍵更新為NULL,所以外鍵必須設(shè)置為可空字段;
  • 關(guān)聯(lián)實體可以不被跟蹤。

DeleteBehavior.ClientSetNull

  • 數(shù)據(jù)庫不會執(zhí)行任何行為;
  • 關(guān)聯(lián)實體必須被跟蹤,將主實體的狀態(tài)標(biāo)記為刪除時,關(guān)聯(lián)實體的外鍵被設(shè)置為null,同時將關(guān)聯(lián)實體的狀態(tài)標(biāo)記為修改,執(zhí)行SaveChange時,先更新關(guān)聯(lián)表的數(shù)據(jù)行,然后刪除主表的數(shù)據(jù)行(此時的行為與DeleteBehavior.SetNull一致);
  • 因為要將外鍵更新為NULL,所以外鍵必須設(shè)置為可空字段;
  • 關(guān)聯(lián)實體必須被跟蹤,否則保存數(shù)據(jù)時會拋出異常。

DeleteBehavior.Restrict

  • 框架不執(zhí)行任何操作,由開發(fā)人員決定關(guān)聯(lián)實體的行為,可以將關(guān)聯(lián)實體的狀態(tài)設(shè)置為刪除,也可以將關(guān)聯(lián)實體的外鍵設(shè)置為null;
  • 因為要修改關(guān)聯(lián)實體的狀態(tài)或外鍵的值,所以關(guān)聯(lián)實體必須被跟蹤。?

以上就是Entity Framework Core關(guān)聯(lián)刪除的詳細(xì)內(nèi)容,更多關(guān)于Entity Framework關(guān)聯(lián)刪除的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Aspx/Asp.net 防注入程序 V1.0

    Aspx/Asp.net 防注入程序 V1.0

    asp下有人寫了防注入的程序,這次看到了一個asp.net的特提供給大家參考。
    2009-10-10
  • ASP.NET?Core中Razor頁面與MVC區(qū)別介紹

    ASP.NET?Core中Razor頁面與MVC區(qū)別介紹

    這篇文章介紹了ASP.NET?Core中Razor頁面與MVC的區(qū)別,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-02-02
  • 淺談ASP.NET Core 2.0 部分視圖(譯)

    淺談ASP.NET Core 2.0 部分視圖(譯)

    本篇文章主要介紹了淺談ASP.NET Core 2.0 部分視圖(譯),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • ASP.NET性能優(yōu)化之局部緩存分析

    ASP.NET性能優(yōu)化之局部緩存分析

    如果我們在開發(fā)網(wǎng)站過程中的緩存策略是不支持頁面局部緩存的,整個架構(gòu)就是不合理的
    2011-10-10
  • Asp.Net Core MVC項目實現(xiàn)多語言實例(Globalization/Localization)

    Asp.Net Core MVC項目實現(xiàn)多語言實例(Globalization/Localization)

    本篇文章主要介紹了Asp.Net Core MVC項目實現(xiàn)多語言實例(Globalization/Localization) ,具有一定的參考價值,有興趣的可以了解一下
    2017-06-06
  • ASP.NET?Core使用Swagger/OpenAPI規(guī)范

    ASP.NET?Core使用Swagger/OpenAPI規(guī)范

    這篇文章介紹了ASP.NET?Core使用Swagger/OpenAPI規(guī)范的方法,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • ASP.NET組件System.Web.Optimization原理及緩存問題詳解

    ASP.NET組件System.Web.Optimization原理及緩存問題詳解

    這篇文章主要介紹了ASP.NET組件System.Web.Optimization的運行原理,及基本的緩存問題,感興趣的小伙伴們可以參考一下
    2016-05-05
  • .NET/C#如何判斷某個類是否是泛型類型或泛型接口的子類型詳解

    .NET/C#如何判斷某個類是否是泛型類型或泛型接口的子類型詳解

    這篇文章主要給大家介紹了關(guān)于.NET/C#如何判斷某個類是否是泛型類型或泛型接口的子類型的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧
    2018-09-09
  • .net中實現(xiàn)listBox左右移動

    .net中實現(xiàn)listBox左右移動

    這里給大家推薦的是一段網(wǎng)友分享的,使用.net實現(xiàn)listBox左右移動的代碼,簡單實用,這里記錄下來,有需要的小伙伴參考下吧。
    2015-03-03
  • ASP.NET MVC生成靜態(tài)頁面的方法

    ASP.NET MVC生成靜態(tài)頁面的方法

    對于網(wǎng)站來說,生成純html靜態(tài)頁面除了有利于seo外,還可以減輕網(wǎng)站的負(fù)載能力和提高網(wǎng)站性能。本篇文章主要介紹了ASP.NET MVC生成靜態(tài)頁面的方法,有興趣的可以了解一下。
    2017-03-03

最新評論

荔浦县| 隆德县| 沙河市| 阿克| 泊头市| 石阡县| 登封市| 湾仔区| 中方县| 全椒县| 香格里拉县| 全州县| 九台市| 察哈| 扶余县| 盐亭县| 宁津县| 嘉义县| 苍南县| 涞水县| 都昌县| 台北市| 西乌珠穆沁旗| 阳泉市| 化州市| 太谷县| 达尔| 固安县| 清涧县| 尚志市| 鞍山市| 三都| 亚东县| 宝坻区| 息烽县| 古蔺县| 莆田市| 鹤峰县| 彰化县| 遂平县| 噶尔县|