内存优化表(EF 核心 5)不支持保存点
Posted
技术标签:
【中文标题】内存优化表(EF 核心 5)不支持保存点【英文标题】:Savepoint is not supported with memory optimized tables (EF core 5) 【发布时间】:2021-03-12 06:38:33 【问题描述】:使用新功能 SavePoints 将 EF 核心版本 3.1 升级到 5(使用事务手册时自动创建)
我在 SQL Server 2016 中有一个名为“内容”的内存优化表。
当我调用“SaveChanges”命令时,系统会抛出异常“内存优化表不支持创建保存点”。如何关闭保存点?
注意:如果我使用 TransactionScope 则通过成功。
请给我解决这种情况的方法 https://docs.microsoft.com/en-us/ef/core/saving/transactions
【问题讨论】:
不要关闭保存点,不要使用显式事务。仅当您使用显式事务时才使用保存点。但在大多数情况下,这不是必需的。SaveChanges
已经使用内部事务。 DbContext 已经实现了 Unit-of-Work 语义,因此不需要显式事务。
为什么还要使用显式事务?您是否尝试使用“通用存储库”anti模式?在这种情况下,您应该检查 No need for Repository and Unit-of-Work with EF Core 和 Repository is the new Singleton
感谢您的回答。我正在为我的项目使用 unitofwork 模型。我有 2 个不强制外键的表 A 和 B。我将新记录添加到表 A 并保存到 DB 并生成 id。之后,我使用之前从表 A 生成的 id 将信息记录添加到表 B 中。为了数据完整性,我必须将其全部包装在一个显式事务中
这是你的错误。你不需要额外的工作单元,你已经有了一个非常好的工作单元。 I have to wrap it all in one explicit transaction for data integrity
不,您没有,您在使用存储库反模式时破坏了完整性,现在您必须通过添加另一个事务来掩盖这一点。不要那样做
阅读我发布的链接。在现有 UoW 之上,您不需要另一个 UoW。通过在每次“CRUD”操作后尝试执行一个SaveChanges
,您破坏了 UoW 并不得不引入一个事务。然而,您的 INSERT
可以轻松执行 30 次更新和 60 次删除以及另外 41 次插入,而不是您认为自己编写的单个 Insert
【参考方案1】:
我想在没有外键的两个表中插入行。
在 startup.cs 文件中
public void ConfigureServices(IServiceCollection services)
services.AddHealthChecks();
services.AddDbContext<wUtilityContentContext>(opts => opts.UseSqlServer(
Algorithm.Decrypt(Configuration["ConnectionStrings:wUtilityContent_ConnectionString"]),
b => b.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name)));
services.AddUnitOfWorkPool(optionsBuilder =>
optionsBuilder.AddUnitOfWork<wUtilityContentContext>("Content");
);
services.AddScoped<IContentUow, ContentUow>();
services.AddScoped<AuditCoreLog>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
....
在 ContentService.cs 文件中
public class ContentServices : ContentServiceBase
private readonly AuditCoreLog _auditLog;
private readonly IContentUow _contentUow;
public ContentServices(IContentUow contentUow, AuditCoreLog auditLog)
_contentUow = contentUow;
_auditLog = auditLog;
public override Task<MessageResponse> CategoryInsertUpdate(CategoryInsertUpdate_Request request, ServerCallContext context)
var response = new MessageResponse() ;
try
int _RESPONSE_EXISTED_CATE = -2;
int _RESPONSE_NOT_EXISTS_CATE = -3;
int _nHotOrder = 0;
var findnHotOrder = _contentUow.Category.Where(p => p.ParentId == request.ParentId).ToList();
if (findnHotOrder != null && findnHotOrder.Count > 0)
_nHotOrder = findnHotOrder.Max(x => x.OrderNo).GetValueOrDefault();
var insertCategory = _contentUow.Category.Add(new TblCategory()
ParentId = request.ParentId,
Alias = request.Alias,
OrderNo = _nHotOrder + 1,
Status = request.Status,
CreatedDate = DateTime.Now,
CreatedUser = request.CreatedUser,
SystemId = request.SystemId,
ImageUrl = request.ImageUrl
);
_contentUow.SaveChanges(); //savechange to DB -> get id identity
var _categoryId = insertCategory.Entity.Id;
var insertCategoryContent_vi = _contentUow.CategoryContent.Add(new TblCategoryContent()
CategoryId = _categoryId,
CategoryName = request.CategoryNameVi,
CategoryContent = request.CategoryContentVi,
LanguageId = (int)PaymentApps_PaymentLanguage.VN
);
var insertCategoryContent_en = _contentUow.CategoryContent.Add(new TblCategoryContent()
CategoryId = _categoryId,
CategoryName = request.CategoryNameEn,
CategoryContent = request.CategoryContentEn,
LanguageId = (int)PaymentApps_PaymentLanguage.EN
);
_contentUow.SaveChanges();
_contentUow.CommitTransaction();
response.ResponseStatus = ErrorCodes.SUCCESS;
catch (Exception ex)
response.ResponseStatus = ErrorCodes.SYSTEM_ERROR;
_contentUow.RollbackTransaction();
【讨论】:
以上是关于内存优化表(EF 核心 5)不支持保存点的主要内容,如果未能解决你的问题,请参考以下文章