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

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

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

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

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

我們先來(lái)看一看SQL Server中支持的行為。在創(chuàng)建外鍵約束時(shí),可以指定關(guān)聯(lián)表在主表刪除行時(shí),對(duì)依賴的數(shù)據(jù)如何執(zhí)行操作。例如下面的SQL語(yǔ)句,[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]末尾的語(yǔ)句是ON DELETE SET NULL,表示當(dāng)主表的數(shù)據(jù)行刪除時(shí),自動(dòng)將關(guān)聯(lián)表數(shù)據(jù)行的外鍵更新為NULL。

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

1.ON DELETE NO ACTION

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

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

語(yǔ)句已終止。

2.ON DELETE CASCADE

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

3.ON DELETE SET NULL

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

4.ON DELETE SET DEFAULT

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

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

定義實(shí)體

我們先定義兩個(gè)實(shí)體Order、OrderDetail分別表示訂單和訂單明細(xì);其中Order與OrderDetail的關(guān)系是一對(duì)多,在OrderDetail實(shí)體中OrderID表示外鍵,依賴于Order實(shí)體中的主鍵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)實(shí)體

在DbContext中OnModelCreating方法中,我們使用 Fluent API 配置實(shí)體中之間的關(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枚舉,分別有如下四個(gè)值:

    public enum DeleteBehavior
    {
        Cascade,

        SetNull,

        ClientSetNull,

        Restrict
    }    

這四個(gè)枚舉值的分別表示不同的行為,這也是我們今天的重點(diǎn)。

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

我們分別使用使用這這個(gè)枚舉值,來(lái)創(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();
            }
        }
        

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

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

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

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

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

        [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ù)上面的測(cè)試結(jié)果,我們可以出得如下結(jié)論:

DeleteBehavior.Cascade

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

DeleteBehavior.SetNull

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

DeleteBehavior.ClientSetNull

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

DeleteBehavior.Restrict

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

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

相關(guān)文章

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

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

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

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

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

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

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

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

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

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

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

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

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

    ASP.NET組件System.Web.Optimization原理及緩存問(wèn)題詳解

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

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

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

    .net中實(shí)現(xiàn)listBox左右移動(dòng)

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

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

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

最新評(píng)論

武冈市| 枣强县| 福贡县| 阿勒泰市| 兖州市| 永仁县| 吴川市| 柳州市| 克拉玛依市| 福贡县| 平乐县| 滁州市| 华安县| 锡林浩特市| 婺源县| 山西省| 江津市| 长春市| 丹寨县| 长葛市| 新营市| 正阳县| 门源| 衡东县| 淅川县| 苍南县| 达日县| 于都县| 洪泽县| 宕昌县| 隆昌县| 普洱| 镇江市| 遵义市| 河间市| 林芝县| 乐亭县| 友谊县| 盐津县| 柯坪县| 兴山县|