上周我有一个我试图重新创建的错误。一段现有代码在数据库上进行了大量插入。但是,数据库中不允许重复的值旧代码在每个带有SaveChanges的AddObject之后都会对数据库进行更改。这表现不太好。因此,不是每次我在每1000条记录之后保存它而保存它(并且在事务中执行此操作,但这与此示例无关)。
下面的代码概述了我的所作所为。
TestEntities test = new TestEntities();
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
string q = j.ToString();
if (!test.warehouses.Any(x => x.combi == q))
{
warehouse wh = new warehouse();
wh.combi = j.ToString();
wh.ean = j.ToString();
test.warehouses.AddObject(wh);
}
}
}
test.SaveChanges();
我不知道的是,实体框架只查询数据库中的数据而不查询待处理的数据,因此任何查询都不会对数据库产生任何结果(我假设会有结果。)因此,这在上面的代码中导致不需要的重复。
现在我解决了它,很快就将所有对象存储在内存中,然后将它们存储在数据库中。这有效,但在代码中会产生大量开销。有办法解决这个问题吗?您能告诉EF处理数据库和挂起的更改吗?所有ORM都是这样的吗?
谢谢, 帕特里克
答案 0 :(得分:1)
面对类似的问题,我决定像你一样检查数据库并检查本地数据:
if( !test.warehouses.Local.Any(x => x.combi == q )
&& !test.warehouses.Any(x => x.combi == q ) )
这应该有用。
修改强> 但事实并非如此。但是,这样做:
var isLocal = ( test as System.Data.Objects.ObjectContext ).ObjectStateManager
.GetObjectStateEntries( System.Data.EntityState.Added )
.Any( x => (x.Entity as warehouse).combi == q );
if( !isLocal && !test.warehouses.Any( x => x.combi == q ) ) {
// ...
}
我必须注意IDbSet<>
(我的代码首先使用而不是模型设计者创建的ObjectSet<>
)具有.Local
属性,因此无需查询ObjectStateManager。我知道代码首先是完全不同的东西,但你也可以非常高效:使用Microsoft SQL Server Management Studio设计数据库并在默认情况下从Entity Framework Power Tools运行优秀的逆向工程师代码或定制(如果需要)T4模板几乎可以获得任何东西。 http://en.wiktionary.org/wiki/your_mileage_may_vary