开发中&使用Entity Framework学习,当我在模型中运行一个实体的测试时,我对插入有一个奇怪的问题。具体来说,问题是在一起运行一些测试时。我会自己解释一下:
我的模型中有一个名为“DtoCategoria”的实体,有2个成员:id:Int32和name:string,映射到一个表,其中id是一个标识列。这很好,很简单。
我有一个名为CadCategoria的DTO数据访问层,我在这里创建了一个插入方法,如:
public class CadCategoria
{
protected readonly CUENTASEntities bd = Singletons.bd;
public bool add(EntityObject entity)
{
try
{
bd.AddObject(EntitySet, entity);
return bd.SaveChanges() > 0;
}
catch (Exception e)
{
bd.Detach(entity);
return false;
}
}
// and some other methods... update, delete, etc.
}
以及其他一些通用方法以及更新和删除。我通过应用程序中的层与单例模式共享上下文,如下所示:
public class Singletons
{
public static CUENTASEntities bd;
static Singletons()
{
bd = new CUENTASEntities();
}
}
从现在开始看起来很好。但是,我创建了一些单元测试,看看是否所有东西都是正确的,看起来像:
[TestClass]
public class CadCategoriaTest
{
private CadCategoria bd = new CadCategoria();
[TestMethod]
public void addTest()
{
var catAdd = new DtoCategoria { name= "cat 1" };
Assert.IsTrue(bd.add(catAdd));
bd.delete(catAdd);
}
[TestMethod]
public void deleteTest()
{
var catDel = new DtoCategoria { name= "cat 2" };
bd.add(catDel);
Assert.IsTrue(bd.delete(catDel));
Assert.IsFalse(bd.delete(new DtoCategoria { name= "not exists", id = -1 }));
}
[TestMethod]
public void updateTest()
{
var a = new DtoCategoria { name= "cat 3" };
bd.add(a);
a.nombre = "name modified";
Assert.IsTrue(bd.update(a));
var b = bd.get(-1);
Assert.IsFalse(bd.update(b));
bd.delete(a);
}
}
现在出现了一个额外的事情:
错误发生在测试的第二行:bd.add(a);这会在上下文的SaveChanges方法中引发OptimisticConcurrencyException。
知道为什么我有一个带有标识列的插入的并发异常?并且只有与删除测试方法结合使用?当与add测试结合使用时,它也不会发生,也会执行“添加”操作??
我担心如果测试失败,它也可能在真正的应用程序中失败。对于没有标识列ID为PK的其他DTO,不会发生这种情况。
有什么想法吗?非常感谢!!!
塞吉
答案 0 :(得分:0)
嗯,我想我终于找到了这个问题。它与Singleton模式无关。事实是我的删除测试试图删除不存在的对象,只是为了检查方法是否返回false:
Assert.IsFalse(bd.delete(new DtoCategoria { name= "not exists", id = -1 }));
但是在bd.delete方法中,我忘了从上下文中删除未存在的对象,所以下次我尝试执行context.SaveChanges()时,再次删除错误的对象是三分之一,所以再次引发OptimisticException,因为没有删除的行。
这是我的bd.delete方法:
public bool delete(EntityObject entity)
{
try
{
if (entity.EntityKey == null)
entity.EntityKey = bd.CreateEntityKey(EntitySet, entity);
if (entity.EntityState == EntityState.Detached)
bd.AttachTo(EntitySet, entity);
bd.DeleteObject(entity);
return bd.SaveChanges() > 0;
}
catch (Exception e)
{
bd.Detach(entity);
return false;
}
}
解决方案是catch部分中的bd.Detach(entity);
命令,告诉上下文忘记这个模拟实体。快速浏览SQL profiler给了我答案。
这就是为什么订单很重要:删除然后更新导致更新崩溃。保留删除作为最后一个,工作正常,因为没有更多的SaveChanges()到上下文。
感谢您的病人@Craig,并对给您带来的不便表示抱歉。
塞吉。