日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Entity Framework Core 软删除与查询过滤器

發(fā)布時(shí)間:2023/12/4 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Entity Framework Core 软删除与查询过滤器 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

注意:我使用的是 Entity Framework Core 2.0 (2.0.0-preview2-final)。正式版發(fā)布后,功能可能存在變動(dòng)。

繼續(xù)探索Entity Framework Core 2.0,今天我將探討如何輕松使用軟刪除(或邏輯刪除)。我的意思是以透明的方式實(shí)現(xiàn)軟刪除,例如,您是物理上的刪除行。要實(shí)現(xiàn)軟刪除,您需要添加一列以指示該行數(shù)據(jù)是否被邏輯刪除。如果您想知道該行被刪除,可以使用布爾列,如果您想知道刪除的時(shí)間,可以使用日期列。其次是更改所有查詢,使用此列過(guò)濾結(jié)果集;您還需要將刪除語(yǔ)句替換成為更新語(yǔ)句。

現(xiàn)在我們來(lái)看看如何用 Entity Framework Core 來(lái)實(shí)現(xiàn)這兩件事!

添加IsDeleted列

實(shí)體框架核心提供了非常靈活的映射。在上一篇關(guān)于跟蹤列(英文原文)的博客中,您將找到映射列的3種方法。在介紹中,我已經(jīng)說(shuō)過(guò)軟刪除應(yīng)該是透明的,所以我決定在類型中不暴露IsDeleted屬性。類型定義如下:

public class Blog{ ? ?

public int BlogId { get; set; } ? ?
public string Url { get; set; } ?
?public List<Post> Posts { get; set; } }
?
?public class Post{ ?
? ?public int PostId { get; set; } ?
? ? ?public string Title { get; set; } ?
? ? ??public string Content { get; set; } ?
? ? ?? ?public int BlogId { get; set; } ?
? ? ?? ??public Blog Blog { get; set; } }

現(xiàn)在,我們需要向 Entity Framework Core 指明類型有一個(gè)附加列:

public class BloggingContext : DbContext{ ?

?public DbSet<Blog> Blogs { get; set; } ?
? ?
? ?public DbSet<Post> Posts { get; set; } ? ?
? ?
? ?protected override void OnModelCreating(ModelBuilder modelBuilder) ? ?{ ? ? ? ?base.OnModelCreating(modelBuilder);modelBuilder.Entity<Post>().Property<bool>("IsDeleted");} }

更改插入、刪除查詢

Entity Framework Core 使用ChangeTracker存儲(chǔ)所有的更改。您可以在EF生成SQL語(yǔ)句和執(zhí)行這些語(yǔ)句之前修改ChangeTracker。

public class BloggingContext : DbContext{ ?

? ?public override int SaveChanges(bool acceptAllChangesOnSuccess) ? ?{OnBeforeSaving(); ? ? ?
? ?return base.SaveChanges(acceptAllChangesOnSuccess);} ?
? ?
? ?public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default(CancellationToken)) ? ?{OnBeforeSaving(); ? ? ?
? ? ?return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);} ?
? ? ?
? ? ??private void OnBeforeSaving() ? ?{ ?
? ? ?? ? ?foreach (var entry in ChangeTracker.Entries<Post>()){ ? ? ? ? ?

? ? ? ? ?switch (entry.State){ ? ? ? ? ? ?
? ? ? ? ? ? ?? ?case EntityState.Added:entry.CurrentValues["IsDeleted"] = false; ? ?
? ? ? ? ? ? ?? ? ? ? ? ? ? ? ? ?break; ? ? ?
? ? ? ? ? ? ?? ??case EntityState.Deleted:entry.State = EntityState.Modified;entry.CurrentValues["IsDeleted"] = true; ? ?
? ? ? ? ? ? ?? ?? ? ?break;}}} }

現(xiàn)在生成以下代碼執(zhí)行的SQL語(yǔ)句:

using (var context = new BloggingContext()) { ?
?var post = new Post { Blog = blog };context.Posts.Add(post);context.SaveChanges(); } exec sp_executesql N'SET NOCOUNT ON;INSERT INTO [Posts] ([BlogId], [Content], [IsDeleted], [Title])VALUES (@p1, @p2, @p3, @p4);SELECT [PostId]FROM [Posts]WHERE @@ROWCOUNT = 1 AND [PostId] = scope_identity();-- @p3 is 0 (false)',N'@p1 int,@p2 nvarchar(4000),@p3 bit,@p4 nvarchar(4000)',@p1=1,@p2=NULL,@p3=0,@p4=NULL ? ?context.Posts.Remove(post);context.SaveChanges(); exec sp_executesql N'SET NOCOUNT ON;UPDATE [Posts] SET [BlogId] = @p0, [Content] = @p1, [IsDeleted] = @p2, [Title] = @p3WHERE [PostId] = @p4;SELECT @@ROWCOUNT;',N'@p4 int,@p0 int,@p1 nvarchar(4000),@p2 bit,@p3 nvarchar(4000)',@p4=1,@p0=1,@p1=NULL,@p2=1,@p3=NULL

插入和刪除請(qǐng)求已經(jīng)被處理,您現(xiàn)在還必須更改所有查詢語(yǔ)句。

更改查詢語(yǔ)句

Entity Framework Core 2.0 引入了一個(gè)新的概念:查詢過(guò)濾器。查詢過(guò)濾器總是在生成的查詢語(yǔ)句后面追加一個(gè)的where子句。這意味著,您可以在模型創(chuàng)建時(shí)聲明一個(gè)實(shí)體的過(guò)濾器,然后將此過(guò)濾器隱式添加到使用該表的生成的每個(gè)查詢語(yǔ)句中。

public class BloggingContext : DbContext{ ?
?protected override void OnModelCreating(ModelBuilder modelBuilder) ? ?{ ? ? ? ?base.OnModelCreating(modelBuilder);modelBuilder.Entity<Post>().Property<bool>("IsDeleted");modelBuilder.Entity<Post>().HasQueryFilter(post => EF.Property<bool>(post, "IsDeleted") == false);} }

讓我們看看查詢過(guò)濾器的作用:

var posts = context.Posts.ToList(); SELECT [p].[PostId], [p].[BlogId], [p].[Content], [p].[IsDeleted], [p].[Title]FROM [Posts] AS [p]WHERE [p].[IsDeleted] = 0 -- Query filter

查詢過(guò)濾器也可以用于關(guān)聯(lián)查詢:

var blogs = context.Blogs.Include(_ => _.Posts); SELECT [_].[BlogId], [_].[Url]FROM [Blogs] AS [_]ORDER BY [_].[BlogId]SELECT [p].[PostId], [p].[BlogId], [p].[Content], [p].[IsDeleted], [p].[Title]FROM [Posts] AS [p]INNER JOIN ( ? ?SELECT [_0].[BlogId] ? ?FROM [Blogs] AS [_0] ) AS [t] ON [p].[BlogId] = [t].[BlogId]WHERE [p].[IsDeleted] = 0 -- Query filterORDER BY [t].[BlogId]

通過(guò)查詢過(guò)濾器實(shí)現(xiàn)軟刪除非常容易 :)

查詢軟刪除的行

如果您要還原已刪除的行,您必須能夠查詢到這些數(shù)據(jù)。這意味著您需要臨時(shí)刪除查詢過(guò)濾器。EF已經(jīng)添加了一種新方法IgnoreQueryFilters來(lái)表明您不希望將查詢過(guò)濾器用于當(dāng)前查詢。

var deletedPosts = context.Posts.IgnoreQueryFilters() ? ? ? ? ? ? ? ?
? ?.Where(post => EF.Property<bool>(post, "IsDeleted") == true);

恢復(fù)已刪除的帖子有點(diǎn)啰嗦,您需要更改跟蹤器中查詢并更新IsDeleted屬性。

var deletedPosts = context.Posts.IgnoreQueryFilters().Where(post => EF.Property<bool>(post, "IsDeleted") == true);
foreach (var deletedPost in deletedPosts) { ?
?var postEntry = context.ChangeTracker.Entries<Post>().First(entry => entry.Entity == deletedPost);postEntry.Property("IsDeleted").CurrentValue = false; } context.SaveChanges();

總結(jié)

使用Entity Framework Core 2.0實(shí)現(xiàn)軟刪除模式非常簡(jiǎn)單,并且可以是透明的。實(shí)際上,您可以無(wú)需更改LINQ代碼的情況下,將軟刪除添加到現(xiàn)有模型中。

相關(guān)文章:?

  • Entity Framework Core 生成跟蹤列

  • 在Apworks數(shù)據(jù)服務(wù)中使用基于Entity Framework Core的倉(cāng)儲(chǔ)(Repository)實(shí)現(xiàn)

  • Entity Framework Core的貼心:優(yōu)雅處理帶默認(rèn)值的數(shù)據(jù)庫(kù)字段

  • Entity Framework Core 實(shí)現(xiàn)MySQL 的TimeStamp/RowVersion 并發(fā)控制

原文地址:http://www.cnblogs.com/tdfblog/p/entity-framework-core-soft-delete-using-query-filters.html


.NET社區(qū)新聞,深度好文,微信中搜索dotNET跨平臺(tái)或掃描二維碼關(guān)注

總結(jié)

以上是生活随笔為你收集整理的Entity Framework Core 软删除与查询过滤器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。