实体框架批量合并

时间:2014-07-31 19:29:52

标签: c# entity-framework-4

我正在尝试使用Entity Framework来执行合并操作。我尝试过使用天真的方法检索记录,然后在代码中执行逻辑,但速度非常慢。

我还研究了如here所述的批量插入库,但它只支持批量插入。

到目前为止,我的解决方法是创建存储过程,为表定义表值类型,使用反射动态生成输入数据表,然后执行存储过程。

当然,这意味着每次我的表定义发生变化时,我现在都必须进入并更改存储过程代码和表值类型。

有没有更好的方法呢?如果我可以从Entity Framework动态生成列定义,这些定义已经有很多帮助。

编辑:我指的是T-SQL Merge:http://msdn.microsoft.com/en-us/library/bb510625.aspx

2 个答案:

答案 0 :(得分:1)

<强>更新

抱歉,我错过了这个问题被标记为EF4。这仅适用于EF更改其映射API的新版本。我把它留在这里是因为同样的事情也可以用旧api完成,我可以找到工作后的代码

免责声明:我是EFUtilities的作者

EFUtilities https://github.com/MikaelEliasson/EntityFramework.Utilities现在支持批量更新。开箱即用它不会让你做合并部分。如果您有办法知道要插入哪些实体以及要更新哪些实体,您可以发出一个插入https://github.com/MikaelEliasson/EntityFramework.Utilities#batch-insert-entities和一个更新https://github.com/MikaelEliasson/EntityFramework.Utilities#batch-update-entities

如果你真的需要合并它可以帮助你构建表。您可以通过此代码访问我在内部使用的元数据。

using (var db = new Context())
{
    var mapping = EfMappingFactory.GetMappingsForContext(db);
    var commentMapping = mapping.TypeMappings[typeof(Comment)];
}

typeMapping包含我用于为批量更新动态构建临时表的所有信息。出于某种原因,我将该代码设为私有,但这里是生成表的sql的方法。所有信息都可在typeMapping上找到。

    private string BuildCreateTableCommand(string schema, string tempTableName, IEnumerable<ColumnMapping> properties)
    {
        var pkConstraint = string.Join(", ", properties.Where(p => p.IsPrimaryKey).Select(c => "[" + c.NameInDatabase + "]"));
        var columns = properties.Select(c => "[" + c.NameInDatabase + "] " + c.DataType);
        var pk = properties.Where(p => p.IsPrimaryKey).Any() ? string.Format(", PRIMARY KEY ({0})", pkConstraint) : "";

        var str = string.Format("CREATE TABLE {0}.[{1}]({2} {3})", schema, tempTableName, string.Join(", ", columns), pk);

        return str;
    }

答案 1 :(得分:0)

最佳解决方案可能取决于您的合理操作&#34;合并操作&#34;。

如果你的意思是你想要从集A中已经存在的集合(table,csv-file或其他)B中插入实体,你可以< / p>

  1. 为您的实体定义合适的GetHashCodeEquals方法
  2. B中的所有现有记录一次性读入内存(假设它们适合内存),将它们放入HashSet h
  3. A读取所有实体,计算A\h,这应该非常快,然后将A\h插入B,可能使用批量插入库。
  4. 这里的关键是避免为A中的每个元素进行数据库查找。