gpt4 book ai didi

entity-framework - 未强制执行 EF Core 并发

转载 作者:行者123 更新时间:2023-12-04 08:32:21 32 4
gpt4 key购买 nike

我已按照此处的文档进行操作,并且正在使用 SQL Server 2016。( https://ef.readthedocs.io/en/latest/modeling/concurrency.html )

我在名为 VersionCol 的表中添加了一个时间戳列,然后当我运行 Scaffold-DbContext 时,它会将以下属性放在我的 DbContext 中的表实体上。

entity.Property(e => e.VersionCol)
.IsRequired()
.HasColumnType("timestamp")
.ValueGeneratedOnAddOrUpdate()

它不见了 .IsConcurrencyToken()所以我在自己身上添加了这一点,但在应该遇到并发问题的情况下仍然没有抛出异常。相反,它只是简单地覆盖数据。

有什么我想念的吗?

编辑:

我正在使用数据库优先的方法(所以没有 [Timestamp] 或任何其他注释),并且我的 DbContext 被注入(inject)到服务中,配置为 services.AddScoped<IPoRepository, PoRepository>()在 Startup.cs

它生成一个 public byte[] VersionCol { get; set; }我的模型中的字段,我相信这是正确的。

在我的 PoRepository 中,我尝试使用以下内容更新我的 Po:
public void SavePo(PoListing poListing) {
Po po;

try {
po = _context.Po.Where( p => p.Poid == poListing.PoId ).First();
} catch ( ArgumentNullException ) {
throw new ArgumentNullException( "The PO does not exist." );
}

po.AssignedUserId = poListing.AssignedUserId;
po.VersionCol = poListing.VersionCol;

_context.Entry( po ).State = EntityState.Modified;

_context.SaveChanges();
}

PoListing本质上只是Po的一部分,所以它只有一些列(它不是数据库中的表),并且它在第一次生成时具有Po的VersionCol。如果 PoListing 的 VersionCol 比它所基于的 Po 旧,那么它应该给出一个异常(exception)。

编辑2:

这行得通,但我不知道如何在不需要创建第二个上下文的情况下使其工作,而只需使用注入(inject)的上下文。
public void SavePo(PoListing poListing) {
DbContextOptionsBuilder<TMS_1000Context> options = new DbContextOptionsBuilder<TMS_1000Context>();
options.UseSqlServer( "Server=DEVSQL16;Database=TMS_1000_Dev;Trusted_Connection=True;MultipleActiveResultSets=true" );

TMS_1000Context context1;

try {
po = _context.Po.Where( p => p.Poid == poListing.PoId ).First();
} catch ( ArgumentNullException ) {
throw new ArgumentNullException( "The PO does not exist." );
}

using ( context1 = new TMS_1000Context( options.Options ) ) {
po.AssignedUserId = poListing.AssignedUserId;
po.VersionCol = poListing.VersionCol;

context1.Update( po );

context1.SaveChanges();
}
}

编辑3:

这目前正在工作。还有其他方法吗?
public void SavePo(PoListing poListing) {
Po po;

try {
po = _context.Po.Where( p => p.Poid == poListing.PoId ).First();
} catch ( ArgumentNullException ) {
throw new ArgumentNullException( "The PO does not exist." );
}

po.AssignedUserId = poListing.AssignedUserId;

_context.Entry( po ).Property( u => u.VersionCol ).OriginalValue = poListing.VersionCol;

_context.Update( po );
_context.SaveChanges();
}

最佳答案

我认为发生这种情况的原因是因为 EF Core 跟踪只关心原始值是否与数据库中当前的值相同,如果它们不同,则会引发并发异常。

这是我发现的 3 个修复程序。

  • 更改原始值,使其现在与数据库中存在的值不同。
    public void SavePo(PoListing poListing) {
    Po po;

    try {
    po = _context.Po.Where( p => p.Poid == poListing.PoId ).First();
    } catch ( ArgumentNullException ) {
    throw new ArgumentNullException( "The PO does not exist." );
    }

    po.AssignedUserId = poListing.AssignedUserId;

    _context.Entry( po ).Property( u => u.VersionCol ).OriginalValue = poListing.VersionCol;

    _context.Update( po );
    _context.SaveChanges();
    }
  • 使用 AsNoTracking() 获取实体。现在 EF Core 不仅会比较原始值。
    public void SavePo(PoListing poListing) {
    Po po;

    try {
    po = _context.Po.AsNoTracking().Where( p => p.Poid == poListing.PoId ).First();
    } catch ( ArgumentNullException ) {
    throw new ArgumentNullException( "The PO does not exist." );
    }

    po.AssignedUserId = poListing.AssignedUserId;
    po.VersionCol = poListing.VersionCol;

    _context.Update( po );
    _context.SaveChanges();
    }
  • 从上下文中分离实体。与修复 #2 类似的功能
    public void SavePo(PoListing poListing) {
    Po po;

    try {
    po = _context.Po.Where( p => p.Poid == poListing.PoId ).First();
    } catch ( ArgumentNullException ) {
    throw new ArgumentNullException( "The PO does not exist." );
    }

    po.AssignedUserId = poListing.AssignedUserId;
    po.VersionCol = poListing.VersionCol;

    _context.Entry( po ).State = EntityState.Detached;

    _context.Update( po );
    _context.SaveChanges();
    }
  • 关于entity-framework - 未强制执行 EF Core 并发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38601453/

    32 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com