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();
        }
    }
  • 相关阅读:
    Two Sum II
    Subarray Sum
    Intersection of Two Arrays
    Reorder List
    Convert Sorted List to Binary Search Tree
    Remove Duplicates from Sorted List II
    Partition List
    Linked List Cycle II
    Sort List
    struts2结果跳转和参数获取
  • 原文地址:https://www.cnblogs.com/libingql/p/9109130.html
Copyright © 2011-2022 走看看