gpt4 book ai didi

entity-framework - Entity Framework 代码优先: SaveChanges is not atomic

转载 作者:行者123 更新时间:2023-12-04 07:22:14 27 4
gpt4 key购买 nike

我有以下非常简单的单元测试,它再现了DbContext.SaveChanges不是原子的情况。
我所说的不是原子的,是指可以在所有提交完成之前读取提交的数据。

添加任务:在循环中,添加新的TestEntity和ReferencingEntity。
验证任务:检查是否存在没有任何ReferenceencingEntity引用的TestEntity-由于我添加实体的方式,这不应该发生。

单元测试失败...有什么建议吗?

编辑:
根据公认的答案-为了使用建议的解决方案运行单元测试,请添加InitTest方法:

using (var context = new TestContext())
{
var objectContext = (context as IObjectContextAdapter).ObjectContext;
objectContext.ExecuteStoreCommand(string.Format("ALTER DATABASE [{0}] SET READ_COMMITTED_SNAPSHOT ON", context.GetType().FullName));
}

单元测试:
using System.Data.Entity;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Atlit.Server.Tests.Integration.SessionProcessing
{
class TestContext : DbContext
{
public DbSet<TestEntity> TestEntities { get; set; }
public DbSet<ReferencingEntity> ReferencingEntities { get; set; }
}

class TestEntity
{
public int TestEntityId { get; set; }
}

class ReferencingEntity
{
public int ReferencingEntityId { get; set; }
public TestEntity TestEntity { get; set; }
}

[TestClass]
public class SaveChangesAtomicTest
{
private volatile int m_Count = 3000;
private volatile bool m_Failed = false;

[TestInitialize]
public void InitTest()
{
using (var context = new TestContext())
{
var dbInitializer = new DropCreateDatabaseAlways<TestContext>();
dbInitializer.InitializeDatabase(context);
}
}

private void AddEntities()
{
while (m_Count-- > 0 && !m_Failed)
{
var transactionOptions = new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted };
using (var transactionScope = new TransactionScope(TransactionScopeOption.RequiresNew, transactionOptions))
{
using (var context = new TestContext())
{
var entity = context.TestEntities.Add(new TestEntity());
context.ReferencingEntities.Add(new ReferencingEntity { TestEntity = entity });
context.SaveChanges();
}
transactionScope.Complete();
}
}
}

private void ValidateEntities()
{
while (m_Count > 0 && !m_Failed)
{
if (FreeEntitiesExist())
{
m_Failed = true;
}
}
}

[TestMethod]
public void TestIsSaveChangesAtomic()
{
var addTask = Task.Factory.StartNew(AddEntities);
var readTask = Task.Factory.StartNew(ValidateEntities);

addTask.Wait();
readTask.Wait();

Assert.IsFalse(FreeEntitiesExist(), "sanity failed");
Assert.IsFalse(m_Failed, "test failed");
}

private static bool FreeEntitiesExist()
{
using (var context = new TestContext())
{
return (from entity in context.TestEntities
where !context.ReferencingEntities.Any(re => re.TestEntity.TestEntityId == entity.TestEntityId)
select entity)
.ToArray().Any();
}
}
}
}

最佳答案

尝试使用数据库选项“正在读取提交的快照” = True。

我们有同样的问题。此选项解决了它们。

有关更多信息:

http://msdn.microsoft.com/en-us/library/ms173763.aspx



Add object and its relationships atomically in SQL Server database

关于entity-framework - Entity Framework 代码优先: SaveChanges is not atomic,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16693609/

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