我们有一个可以导入大量数据的系统。数据可以带有不同类型的 xml 文件,并且现在映射到 c# 对象。现在我们希望通过名称(这将是唯一的,但不会是 Id)更新按名称定位的现有对象,或者如果没有匹配的名称则创建新文档。
我们怎样才能以最有效的方式做到这一点?
我们有一个可以导入大量数据的系统。数据可以带有不同类型的 xml 文件,并且现在映射到 c# 对象。现在我们希望通过名称(这将是唯一的,但不会是 Id)更新按名称定位的现有对象,或者如果没有匹配的名称则创建新文档。
我们怎样才能以最有效的方式做到这一点?
如果您不关心检查是否存在,那么您可以执行Bulk Insert。
除此之外,您还需要加载每一个Name
(因为我假设它是独一无二的,正如您所说)。
像这样..
using (var documentSession = documentStore.OpenSession())
{
// We are doing an import, so allow us to do LOTS of queries to the db.
documentSession.Advanced.MaxNumberOfRequestsPerSession = int.MaxValue;
foreach (var foo in newFoosToImport())
{
var existingFoo = documentSession
.Query<Foo>()
.SingleOrDefault(x => x.Name == foo.Name);
if (existingFoo == null)
{
// Doesn't exist, so just save this new data.
documentSession.Store(foo);
}
else
// Map the required new data to the existing object.
MapNewDataToExistingObject(foo, existingFoo);
// Now save the existing.
documentSessionStore(existingFoo);
}
}
// Commit these changes.
documentSession.SaveChanges();
}
此代码方法的另一种替代方法是通过将Names
. 意思是,您将名称列表传递给Where
子句。所以也许通过 10 或 30 Names
。如果存在,则更新这些记录,否则插入。
现在,如果您有一个大型数据集,您可能会考虑将SaveChanges
.
例如。
if (storeCount % 1024 == 0)
{
documentSession.SaveChanges();
}
所以每1024 Stores
,你然后SaveChanges
。不确定这是否有帮助,但这是一个想法。(提示:如果这样做,请确保SaveChanges
在循环之后还有一个,以便提交循环中的最后一组数据)。