zoukankan      html  css  js  c++  java
  • EntityFramework Core笔记:查询数据(3)

    1. 基本查询

    1.1 加载全部数据

    using System.Linq;
    using (var context = new LibingContext())
    {
        var roles = context.Roles.ToList();
    }

    1.2 加载单个实体

    using (var context = new LibingContext())
    {
        var role = context.Roles.FirstOrDefault(t => t.RoleID == 1);
    }
    using (var context = new LibingContext())
    {
        var role = context.Roles.Find(1);
    }

    注:Find()根据主键值查询返回单个实体。

    1.3 筛选条件

    using (var context = new LibingContext())
    {
        var roles = context.Roles
                        .Where(t => t.RoleName == "管理员")
                        .ToList();
    }

    2. 加载关联数据

      Entity Framework Core可以在实体模型中使用导航属性,来加载关联数据。

      常见的3中关联数据加载方式:

      (1)预先加载(Eager Loading):关联数据作为初始查询的一部分从数据库中加载

      (2)显式加载(Explicit Loading):关联数据在后续用到时显式指定从数据中加载

      (3)延迟加载(Lazy Loading):关联数据通过导航属性,以透明方式从数据库中加载

    2.1 预先加载

      使用Include()指定需要包含在查询结果中的关联数据。

    using System.Linq;
    using Microsoft.EntityFrameworkCore;
    using (var context = new LibingContext())
    {
        var categories = context.Categories
            .Include(t => t.Products)
            .ToList();
    }

    2.2 显式加载

      显式加载通过一个导航属性DbContext.Entry(...)API。

    using (var context = new LibingContext())
    {
        var category = context.Categories.Find(1);
    
        context.Entry(category)
            .Collection(t => t.Products)
            .Load();
    
        category.Products.ForEach(product =>
        {
            Console.WriteLine("ProductID:{0},ProductName:{1}", product.ProductID, product.ProductName);
        });
    }

      显式加载通过相关的实体的聚合运算符,而无需加载到内存的操作。

    using (var context = new LibingContext())
    {
        var category = context.Categories.Find(1);
    
        int count = context.Entry(category)
                .Collection(t => t.Products)
                .Query()
                .Count();
    }

      筛选加载到内存的关联实体数据。

    using (var context = new LibingContext())
    {
        var category = context.Categories.Find(1);
    
        var products = context.Entry(category)
                .Collection(t => t.Products)
                .Query()
                .Where(t => t.UnitPrice >= 10)
                .ToList();
    }

    3. 跟踪与非跟踪

    3.1 跟踪查询

      Entity Framework Core跟踪状态的实体,在检测到改动的情况下,调用SaveChanges()时,将持久保存数据库中。

    using (var context = new LibingContext())
    {
        var product = context.Products.Find(1);
        product.UnitPrice = 100m;
    
        context.SaveChanges();
    }

    3.2 非跟踪查询

      非跟踪查询在对查询数据只读情况下,可以加快执行。

    using (var context = new LibingContext())
    {
        var products = context.Products
            .AsNoTracking()
            .ToList();
    }

      更改默认跟踪上下文实例级别的行为:

    using (var context = new LibingContext())
    {
        context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
    
        var products = context.Products
            .ToList();
    }

    3.3 跟踪与投影

      即使查询的结果类型不是实体类型,如果结果包含实体类型它们将仍在默认情况下跟踪。

      在下面的查询,它返回匿名类型的实例Category集将跟踪结果中。

    using (var context = new LibingContext())
    {
        var categories = context.Categories
            .Select(t => new
            {
                Category = t,
                Products = t.Products.Count()
            });
    }

      如果结果集不包含任何实体类型,会不执行任何跟踪。

      在下面的查询,这将返回一个匿名类型使用某些实体(但不实际实体类型的实例)中的值时,没有任何跟踪执行。

    using (var context = new LibingContext())
    {
        var products = context.Products
            .Select(t => new
            {
                ProductID = t.ProductID,
                PrudctName = t.ProductName
            });
    }

    4. 原始SQL查询

      EntityFramework Core使用原始SQL查询限制条件:

      (1)SQL查询返回字段必须属于实体类型

      (2)SQL查询必须返回实体类型的所有属性

    4.1 基本原始SQL查询

      使用FromSql扩展方法,基于原始的 SQL 查询的 LINQ 查询。

    using (var context = new LibingContext())
    {
        var products = context.Products
            .FromSql("SELECT * FROM [dbo].[Product]")
            .ToList();
    }

      使用原始的 SQL 查询来执行存储的过程。

    CREATE PROCEDURE USP_GetProducts
    AS
    BEGIN
        SELECT * FROM [dbo].[Product]
    END
    using (var context = new LibingContext())
    {
        var products = context.Products
            .FromSql("EXECUTE [dbo].[USP_GetProducts]")
            .ToList();
    }

    4.2 传递参数

      SQL参数化可以防止收到SQL注入攻击。

    CREATE PROCEDURE USP_GetProductsByUnitPrice
        @UnitPrice DECIMAL(18, 2)
    AS
    BEGIN
        SELECT * FROM [dbo].[Product]
        WHERE [UnitPrice] >= @UnitPrice
    END
    using (var context = new LibingContext())
    {
        decimal unitprice = 100m;
        var products = context.Products
            .FromSql("EXECUTE [dbo].[USP_GetProducts] {0}", unitprice)
            .ToList();
    }
    using System.Data;
    using System.Data.SqlClient;
    using (var context = new LibingContext())
    {
        var unitprice = new SqlParameter("@UnitPrice", SqlDbType.Decimal);
        unitprice.Value = 100m;
    
        var products = context.Products
            .FromSql("EXECUTE [dbo].[USP_GetProducts] @UnitPrice", unitprice)
            .ToList();
    }

    5. 异步查询

      异步操作使用场景:当等待一个比较耗时的操作时,使用异步来释放当前的托管线程而无需等待,不会阻塞当前线程的运行。

      异步操作在主应用程序线程以外的线程中执行,应用程序可在异步方法执行其任务时继续执行。

      异步查询在数据库中执行查询时可以避免阻止线程。

      Entity Framework Core提供的异步查询扩展方法包括:ToListAsync(),ToArrayAsync(),SingleAsync()等。

    using System.Threading.Tasks;
    using Microsoft.EntityFrameworkCore;
    public async Task<List<Product>> GetProductsAsync()
    {
        using (var context = new LibingContext())
        {
            return await context.Products.ToListAsync();
        }
    }
  • 相关阅读:
    maven中使用命令下载指定pom.xml中的jar文件
    资源监控平台
    PerfDog的使用教程
    compile ffmepg with amr
    matplotlib
    总线通信
    阿里云NAS文件迁移项目实践
    React diff算法
    IDE Eval Resetter:JetBrains 全家桶无限试用插件
    IntelliJ IDEA 2021.2.0 官方正版
  • 原文地址:https://www.cnblogs.com/libingql/p/9109130.html
Copyright © 2011-2022 走看看