浅谈使用 Entity Framework (EF) 查询数据库处理数据集

发布时间 2023-08-11 16:12:36作者: yuteacher

简介

Entity Framework (EF) Core 是轻量化、可扩展、开源和跨平台版的常用 Entity Framework 数据访问技术。

EF Core 可用作对象关系映射程序 (O/RM),这可以实现以下两点:

  • 使 .NET 开发人员能够使用 .NET 对象处理数据库。
  • 无需再像通常那样编写大部分数据访问代码。

对于 EF Core,使用模型执行数据访问。

  • 模型:由实体类和表示数据库会话的上下文对象构成。 上下文对象允许查询并保存数据
  • 获取查询结果:使用语言集成查询 (LINQ) 从数据库检索实体类的实例并获取 IQueryable 结果集。
  • 修改结果值:对于获取的 IQueryable 结果集,在内存中修改这些实体对象的属性
  •  保存更改:使用 EF 的上下文(DbContext)来保存更改。这将会追踪所修改的对象,并在适当的时候将更改应用到数据库。

使用

首先建立仓储,这里使用构造函数注入。

//Inventory为模型

private readonly IRepository<Inventory> _inventory;

    public InventoryService(IRepository<Inventory> inventory, IRepository<WareHouse> warehouse)

    {

      _inventory = inventory;

    }

获取 IQueryable 结果集,为方便处理结果集,调用ToList()方法。

var InventoryID=_inventory.Where(u => u.ProductName==inventoryDto.ProductName)

        .Where(u => u.LibraryLocation==inventoryDto.LibraryLocation)

        .Where(u => u.OldNew==inventoryDto.OldNew).ToList();

对结果集更新

InventoryID[0].UpdUate = DateTime.Now;

        newEntity = InventoryID[0].Update();

文中使用Furion框架更新保存数据库。若使用原生方式,则使用 SaveChanges 方法将修改保存到数据库。

实体跟踪

InventoryID转换为 List<>,则查询结果将立即从数据库中加载到内存中作为一个列表。由于默认情况下,Entity Framework Core跟踪返回实体类型的查询。 跟踪查询意味着对实体实例所做的任何更改都由 SaveChanges持久化。SaveChanges期间检测到的任何更改将保存到数据库中。这意味着我们如果在内存中对列表进行修改,不管有没有使用SaveChanges ,都将把更改保存回数据库中。在开发过程中,这种默认设置是极其不方便和对数据库不安全的。

因此,需要对默认设置进行修改,以下为三种修改形式。

1.全局设置

在默认DbContext中添加

public class DefaultDbContext : AppDbContext<DefaultDbContext>

  {

    public DefaultDbContext(DbContextOptions<DefaultDbContext> options) : base(options)

    {

      ChangeTracker.AutoDetectChangesEnabled = false; // 禁用自动检测更改

    }

  }

2. 建立仓储时设置

如果使用构造函数建立仓储时追加

public InventoryService(IRepository<Inventory> inventory, IRepository<WareHouse> warehouse)

    {

      _inventory = inventory;

// 禁用自动检测更改

      _inventory.ChangeTracker.AutoDetectChangesEnabled = false;

    }

3. 实例级别设置

调用.AsNoTrackingWithIdentityResolution()方法

var InventoryID=_inventory.Where(u => u.ProductName==inventoryDto.ProductName)

        .Where(u => u.LibraryLocation==inventoryDto.LibraryLocation).Where(u => u.OldNew==inventoryDto.OldNew).AsNoTrackingWithIdentityResolution().ToList();

修改完默认跟踪设置后,若想同步至数据,则必须使用SaveChanges方法。