<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      03-EF Core筆記之查詢數據

      EF Core使用Linq進行數據查詢。

      基本查詢

      微軟提供了一百多個示例來演示查詢,地址:https://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b

      我們可以通過下面的代碼進行簡單的查詢:

      //獲取全部數據
      var blogs = context.Blogs.ToList();
      
      //獲取單個實體
      var blog = context.Blogs.Single(b => b.BlogId == 1);
      
      //篩選
      var blogs = context.Blogs
          .Where(b => b.Url.Contains("dotnet"))
          .ToList();
      

      加載關聯數據

      EF Core有三種常見模型來加載關聯數據:

      • 預先加載:表示從數據庫中加載關聯數據,作為初始查詢的一部分
      • 顯式加載:表示稍后從數據庫中顯式加載關聯數據
      • 延遲加載:表示在訪問關聯數據時,再從數據庫中加載關聯數據

      預先加載

      使用Include方法指定要包含在查詢結果中的關聯數據。例如:

      using (var context = new BloggingContext())
      {
          var blogs = context.Blogs
              .Include(blog => blog.Posts)
              .Include(blog => blog.Owner)
              .ToList();
      }
      

      關聯數據可以是有層級的,可通過鏈式調用ThenInclude,進一步包含更深級別的關聯數據。:

      using (var context = new BloggingContext())
      {
          var blogs = context.Blogs
              .Include(blog => blog.Posts)
                  .ThenInclude(post => post.Author)
                      .ThenInclude(author => author.Photo)
              .Include(blog => blog.Owner)
                  .ThenInclude(owner => owner.Photo)
              .ToList();
      }
      

      如果更改查詢,從而使其不再返回查詢以之為開頭的實體類型的實例,則會忽略 include 運算符。例如:

      using (var context = new BloggingContext())
      {
          var blogs = context.Blogs
              .Include(blog => blog.Posts)
              .Select(blog => new
              {
                  Id = blog.BlogId,
                  Url = blog.Url
              })
              .ToList();
      }
      

      此時EF Core會忽略包含,并生成警告日志。

      顯式加載

      通過 DbContext.Entry(...) API 顯式加載導航屬性。例如:

      using (var context = new BloggingContext())
      {
          var blog = context.Blogs
              .Single(b => b.BlogId == 1);
      
          context.Entry(blog)
              .Collection(b => b.Posts)
              .Load();
      
          context.Entry(blog)
              .Reference(b => b.Owner)
              .Load();
      }
      

      延遲加載

      使用延遲加載的最簡單方式是通過安裝 Microsoft.EntityFrameworkCore.Proxies 包,并通過調用 UseLazyLoadingProxies 來啟用該包。 例如:

      protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
          => optionsBuilder
              .UseLazyLoadingProxies()
              .UseSqlServer(myConnectionString);
      

      或者在ServiceConfigure中,調用services.AddDbContext方法時啟用:

      services.AddDbContext<BloggingContext>(
          b => b.UseLazyLoadingProxies()
                .UseSqlServer(myConnectionString));
      

      EF Core 延遲加載需要屬性必須具有是共有的,且具有virtual修飾符,只有這樣才可以被子類重寫。為何要這樣做,可以參考我之前的文章《Castle DynamicProxy基本用法(AOP)》。

      下面的代碼演示了延遲加載的用法:

      public class Blog
      {
          public int Id { get; set; }
          public string Name { get; set; }
      
          public virtual ICollection<Post> Posts { get; set; }
      }
      
      public class Post
      {
          public int Id { get; set; }
          public string Title { get; set; }
          public string Content { get; set; }
      
          public virtual Blog Blog { get; set; }
      }
      

      此時EF Core會使用代理類進行延遲加載數據。

      EF Core還提供了不使用代理的方式進行延遲加載,此方法需要向實體類中注入ILazyLoader實例,并通過該實例實現get訪問:

      public class Blog
      {
          private ICollection<Post> _posts;
      
          public Blog()
          {
          }
      
          private Blog(ILazyLoader lazyLoader)
          {
              LazyLoader = lazyLoader;
          }
      
          private ILazyLoader LazyLoader { get; set; }
      
          public int Id { get; set; }
          public string Name { get; set; }
      
          public ICollection<Post> Posts
          {
              get => LazyLoader.Load(this, ref _posts);
              set => _posts = value;
          }
      }
      

      此種方法需要注入ILazyLoader,從而造成更多的包依賴。

      使用EF Core延遲加載,可能會造成循環引用,此時無法使用Json.Net進行序列化,需要對此進行一些配置:

      public void ConfigureServices(IServiceCollection services)
      {
          services.AddMvc()
              .AddJsonOptions(
                  options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
              );
      }
      

      客戶端 vs. 服務器

      EF Core支持部分查詢在客戶端進行、部分查詢發送到服務器,此種情況下可能會造成性能問題。

      當發生客戶端篩選數據的時候,EF Core會發出警告,也可以配置當發生客戶端篩選時拋出異常:

      protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
      {
          optionsBuilder
              .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EFQuerying;Trusted_Connection=True;")
              .ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning));
      }
      

      跟蹤和非跟蹤

      默認情況下,EF Core跟蹤查詢返回的實體,如果我們不需要跟蹤查詢返回的實體,則可以通過AsNoTracking方法禁用跟蹤。

      using (var context = new BloggingContext())
      {
          var blogs = context.Blogs
              .AsNoTracking()
              .ToList();
      }
      

      或者在DbContext級別禁用跟蹤:

      using (var context = new BloggingContext())
      {
          context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
      
          var blogs = context.Blogs.ToList();
      }
      

      當使用投影查詢結果時,如果包含實體類型,則會對實體類型執行跟蹤,例如下面的查詢,將會對Blog和Post進行跟蹤:

      using (var context = new BloggingContext())
      {
          var blog = context.Blogs
              .Select(b =>
                  new
                  {
                      Blog = b,
                      Posts = b.Posts.Count()
                  });
      }
      

      另外,如果查詢結果中不包含任何實體類型,則不執行跟蹤。例如:

      using (var context = new BloggingContext())
      {
          var blog = context.Blogs
              .Select(b =>
                  new
                  {
                      Id = b.BlogId,
                      Url = b.Url
                  });
      }
      

      原始SQL查詢

      當Linq無法滿足查詢需求,或因為使用Linq生成效率比較低的SQL查詢時,可以考慮使用原始SQL進行查詢。EF Core支持原始SQL語句和存儲過程。

      原始SQL語句:

      var blogs = context.Blogs
          .FromSql("SELECT * FROM dbo.Blogs")
          .ToList();
      

      存儲過程:

      var blogs = context.Blogs
          .FromSql("EXECUTE dbo.GetMostPopularBlogs")
          .ToList();
      

      參數傳遞

      當使用原始SQL進行查詢時,必須使用參數化查詢以抵御SQL注入攻擊。

      好的一點是,EF Core在設計時就替我們考慮了如何防御SQL注入攻擊,因此當我們使用FromSql方法時,參數中如果有使用到拼接字符串的情況,則會自動為我們生成SQL查詢參數,例如:

      var user = "johndoe";
      
      var blogs = context.Blogs
          .FromSql($"EXECUTE dbo.GetMostPopularBlogsForUser {user}")
          .ToList();
      

      上面的SQL語句雖然看上去像是直接拼接的字符串,其實EF Core已經為我們生成了查詢參數。

      當然了,我們也可以手工創建查詢參數:

      var user = new SqlParameter("user", "johndoe");
      
      var blogs = context.Blogs
          .FromSql("EXECUTE dbo.GetMostPopularBlogsForUser @user", user)
          .ToList();
      

      當數據庫的存儲過程使用了命名參數時,手工創建查詢參數將會派上用場:

      var user = new SqlParameter("user", "johndoe");
      
      var blogs = context.Blogs
          .FromSql("EXECUTE dbo.GetMostPopularBlogs @filterByUser=@user", user)
          .ToList();
      

      拼接Linq

      當我們使用原始SQL查詢時,EF Core仍然支持我們使用linq編寫查詢語句。在執行查詢時,EF Core會檢查我們的sql語句是否支持拼接,如果支持的情況下,則會將linq過濾語句拼接為sql一并發送到數據庫進行查詢。

      跟蹤

      原始SQL中的跟蹤與Linq查詢的跟蹤方式一致。

      關聯數據

      原始SQL中查詢關聯數據的方式與Linq查詢的關聯方式一致。

      全局篩選器

      全局篩選器對于軟刪除和多租戶非常有用。定義方式如下:

      protected override void OnModelCreating(ModelBuilder modelBuilder)
      {
          modelBuilder.Entity<Blog>().Property<string>("TenantId").HasField("_tenantId");
      
          // Configure entity filters
          modelBuilder.Entity<Blog>().HasQueryFilter(b => EF.Property<string>(b, "TenantId") == _tenantId);
          modelBuilder.Entity<Post>().HasQueryFilter(p => !p.IsDeleted);
      }
      

      我們可以在特定的查詢中禁用全局篩選器:

      blogs = db.Blogs
          .Include(b => b.Posts)
          .IgnoreQueryFilters()
          .ToList();
      
      posted @ 2019-07-15 00:37  拓荒者IT  閱讀(6766)  評論(0)    收藏  舉報
      皮膚配置 參考地址:https://www.yuque.com/awescnb/user
      主站蜘蛛池模板: 亚洲日韩欧洲乱码av夜夜摸 | XXXXXHD亚洲日本HD| 99久久久无码国产精品免费 | 永久黄网站色视频免费直播| 国产日韩精品欧美一区灰| 人妻少妇精品无码专区二区 | 深夜在线观看免费av| 欧美人禽杂交狂配| 高潮喷水抽搐无码免费| 国产精品国产三级国产专业| 成人午夜电影福利免费| 亚洲a免费| 亚洲香蕉免费有线视频| 丰满人妻熟妇乱又伦精品软件| 亚洲天堂成人黄色在线播放| 国产成人拍国产亚洲精品| 91无码人妻精品一区二区蜜桃| 又爽又黄又无遮挡的激情视频| 国产成人综合亚洲欧美日韩| 亚洲日本乱码熟妇色精品| 精品少妇av蜜臀av| 国产在线精品一区二区三区| 免费人妻无码不卡中文18禁| 韩国美女福利视频一区二区| 无码内射中文字幕岛国片 | 中文字幕人成无码免费视频 | 天堂V亚洲国产V第一次| 一边吃奶一边摸做爽视频| 麻豆精产国品一二三区区| 午夜福利片1000无码免费| 中文字幕日韩精品有码| 无码人妻久久一区二区三区app| 99久久精品看国产一区| 丁香五月激情图片| 777奇米四色成人影视色区| 人妻系列中文字幕精品| 国产一区二区精品自拍| 免费a级黄毛片| 色噜噜狠狠成人综合| 久久精品国产亚洲精品2020| 无码人妻丝袜在线视频|