网站首页 > 开源技术 正文
概述:长期以来,使用实体框架 (EF) 一直是应用程序设计人员面临的挑战。这是因为大多数应用程序设计人员被实体框架的 ORM 性质分散了注意力,并且无法超越它。Entity Framework 8.0 是一个经过深思熟虑的库,在过去十年中不断发展,具有许多有用的功能。工具箱中最新升级的功能是精心设计的数据库迁移。在应用程序中使用实体框架之前,我们需要了解三个重要的策略:1 — 延迟加载2 — CRUD 操作3 — 使用 TransactionScope1 — 延迟加载在生产就绪型应用程序中使用 Entity Framework 8.0 的第一步是使用_延迟加载_。Entity Framework 中
长期以来,使用实体框架 (EF) 一直是应用程序设计人员面临的挑战。这是因为大多数应用程序设计人员被实体框架的 ORM 性质分散了注意力,并且无法超越它。
Entity Framework 8.0 是一个经过深思熟虑的库,在过去十年中不断发展,具有许多有用的功能。工具箱中最新升级的功能是精心设计的数据库迁移。
在应用程序中使用实体框架之前,我们需要了解三个重要的策略:
1 — 延迟加载
2 — CRUD 操作
3 — 使用 TransactionScope
1 — 延迟加载
在生产就绪型应用程序中使用 Entity Framework 8.0 的第一步是使用_延迟加载_。
Entity Framework 中的延迟加载意味着我们只加载需要使用和操作的数据。
当然,Entity Framework 也提供了 Eager Loading,以一种快速而肮脏的方式对新应用程序_进行快速原型设计_,但它的使用确实会带来副作用。
事实是,Eager Loading 没有经过优化,无法用于高可用性生产就绪型应用程序。
在 Entity Framework 8.0 中,默认情况下启用延迟加载。
下面是我们如何在将 Entity Framework 8.0 的 DbContext 注入任何类构造函数之前对其进行初始化:
var myConnectionString = "/* some EF 8.0 connection string here */";
services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer(myConnectionString), ServiceLifetime.Scoped);
2 — CRUD 操作
第二种策略是改进 CRUD 操作的使用。
以下是如何使用 Entity Framework 优化 CRUD 操作:
创建:保存并忘记
若要使用 Entity Framework 创建记录,请按照下列步骤操作:
1 — 创建实体对象。
2 — 将实体对象添加到 DbContext。
3 – 保存 DbContext 更改。
4 — 将实体对象与 DbContext 状态跟踪分离。
上面,前三个步骤非常标准。不过,这是值得回顾的第四步。
这里的想法是,一旦我们通过将实体对象添加到 DbContext 创建了新的数据库记录,我们必须禁用该对象的更改跟踪,否则实体框架将不会释放该对象并造成不利影响,例如无法在其他地方操作新记录。
以下是我们如何实现上述四个步骤来创建记录:
// Class: CreateUser
public string Username{ get; set; }
public int Execute(MyDbContext dataContext)
{
// Create Entity Object
var rec = new UserDb();
rec.Username = this.Username;
// Add Entity Object to DbContext
dataContext.Add(rec);
// Save Changes (This will create a new record in database)
dataContext.SaveChanges();
// Detach Entity Object to release/unload database record from DbContext
dataContext.Entry(rec).State = EntityState.Detached;
// return newly created record Id
return rec.UserId;
}
检索:加载到映射
若要检索现有记录,请始终仅加载所需的记录。加载后,将它们映射到标准 POCO,并使用这些 POCO 来避免 DbContext 更改跟踪导致的记录锁定。这样,我们的 DbContext 将永远不会锁定数据库记录。
下面是如何使用 Entity Framework 检索记录并将其映射到 POCO:
// Class: GetUser
public int UserId { get; set; }
public UserData Execute(MyDbContext dataContext)
{
// Get Record
var data = (from a in dataContext.Users
where a.UserId == this.UserId
select a).FirstOrDefault();
// did we find the record?
if (data != null)
{
// Map Entity Object to POCO
var obj = this.Mapper.Map<UserData>(data);
// Return POCO to use
return obj;
}
return null;
}
更新:加载、保存和释放
在 Entity Framework 中更新记录应与创建和检索记录的方式相同。
以下是使用实体框架更新记录的步骤:
- 加载数据
- 修改数据
- 保存数据
- 通过不重复使用修改的记录来释放数据。
如前所述,实体框架跟踪对已修改的实体所做的更改。因此,一旦修改并保存了现有实体,我们就不应该重复使用它们。
下面是如何在 Entity Framework 8.0 中执行更新操作的:
// Class: SaveUser
public int UserId { get; set; }
public string Username{ get; set; }
public bool Execute(MyDbContext dataContext)
{
// Retrieve Record
var rec = (from a in dataContext.Users
where a.UserId == this.UserId
select a).FirstOrDefault();
if (rec != null)
{
// Update Record
rec.UserId = this.UserId;
rec.Username = this.Username;
// Save Record Changes
dataContext.SaveChanges();
return true;
}
return false;
}
如果您觉得需要使用更新的实体对象,则不要使用实体对象,而是将实体对象映射到 POCO,并在需要使用的位置引用该 POCO。
删除:加载、删除和忘记
实体框架中的删除与更新非常相似。
以下是我们在 Entity Framework 中删除对象的方法:
// Class: DeleteUser
public int UserId { get; set; }
public bool Execute(MyDbContext dataContext)
{
// Retrieve Record
var rec = from a in dataContext.PhoneNumbers
where a.UserId == this.UserId
select a;
// Delete Record
dataContext.RemoveRange(rec);
// Save Changes
dataContext.SaveChanges();
return true;
}
3 — 使用 TransactionScope
第三个也是最重要的策略是将上述所有 CRUD 操作包装在 TransactionScope 中。
TransactionScope 是一个 .NET 类,一旦使用“_using”_块实例化,它就会将 using 块中包含的所有 CRUD 操作封装在一个事务下。它通过检测事务管理器的可用性来实现。
using (var transactionScope = new TransactionScope())
{
/*
Multiple SQL CRUD Operations where
*/
transactionScope.Complete();
}
在上面的示例中,创建一个 TransactionScope 实例足以将 using 区块中的所有 CRUD 操作包装在一个事务下。我们必须在 TransactionScope 上调用 Complete() 函数来提交更改,否则即使我们单独调用了每个 CRUD 操作的 DbContext.SaveChanges(),所有更改也会回滚。
对于实体框架,TransactionScope 必须与以下配置一起使用,否则我们可能会遇到过早中止的事务。
var transactionOptions =
new TransactionOptions
{
IsolationLevel = IsolationLevel.ReadCommitted,
Timeout = TimeSpan.FromSeconds(30)
};
var transactionFlow = TransactionScopeAsyncFlowOption.Enabled;
using(var scope = new TransactionScope(transactionOptions, transactionFlow))
{
/* Some CRUD Operations here */
}
上面是我们如何为 Entity Framework 8.0 配置 TransactionScope。
将一切结合在一起
最后,我们可以总结上述知识,编写一个创建、检索、更新并在最后删除用户记录的 UnitOfWork:
var transactionOptions =
new TransactionOptions
{
IsolationLevel = IsolationLevel.ReadCommitted,
Timeout = TimeSpan.FromSeconds(30)
};
var transactionFlow = TransactionScopeAsyncFlowOption.Enabled;
using (scope = TransactionScope(transactionOptions, transactionFlow))
{
// Create a User
new CreateUser
{
Username = "testuser"
}.Execute(this.MyDbContext);
// Retrieve a User
var user = new GetUser
{
UserId = 1
}.Execute(this.MyDbContext);
// Update a User
new UpdateUser
{
UserId = 1,
UserName = "testuser-2"
}.Execute(this.MyDbContext);
// Delete a User
new DeleteUser
{
UserId = 1
}.Execute(this.MyDbContext);
// Commit Transaction
transactionScope.Complete();
}
猜你喜欢
- 2024-10-19 Spring Boot中RestTemplate开发实践(2)
- 2024-10-19 浅谈.NET EentityFramework的导航属性
- 2024-10-19 Entity Framework Core-删除数据(删除.net4.0)
- 2024-10-19 EntityFramework Core 2.x/3.x (ef core) 在迁移中自动生成数据库表
- 2024-10-19 今日技术点:使用Entity Framework Core进行数据库迁移
- 2024-10-19 EntityFramework-Plus: 让 EF Core 如虎添翼
- 2024-10-19 Entity Framework Core 插入数据(entity framework教程)
- 2024-10-19 Entity Framework Core-配置(entities framework)
- 2024-10-19 一文带你了解EF Core关系配置 | C# 数据操作系列
- 2024-10-19 一步一步学会Code First EntityFramework autofac实现DDD框架
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- jdk (81)
- putty (66)
- rufus (78)
- 内网穿透 (89)
- okhttp (70)
- powertoys (74)
- windowsterminal (81)
- netcat (65)
- ghostscript (65)
- veracrypt (65)
- asp.netcore (70)
- wrk (67)
- aspose.words (80)
- itk (80)
- ajaxfileupload.js (66)
- sqlhelper (67)
- express.js (67)
- phpmailer (67)
- xjar (70)
- redisclient (78)
- wakeonlan (66)
- tinygo (85)
- startbbs (72)
- webftp (82)
- vsvim (79)
本文暂时没有评论,来添加一个吧(●'◡'●)