我正在尝试使用Entity Framework来执行合并操作。我尝试过使用天真的方法检索记录,然后在代码中执行逻辑,但速度非常慢。
我还研究了如here所述的批量插入库,但它只支持批量插入。
到目前为止,我的解决方法是创建存储过程,为表定义表值类型,使用反射动态生成输入数据表,然后执行存储过程。
当然,这意味着每次我的表定义发生变化时,我现在都必须进入并更改存储过程代码和表值类型。
有没有更好的方法呢?如果我可以从Entity Framework动态生成列定义,这些定义已经有很多帮助。
编辑:我指的是T-SQL Merge:http://msdn.microsoft.com/en-us/library/bb510625.aspx
答案 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>
GetHashCode
和Equals
方法B
中的所有现有记录一次性读入内存(假设它们适合内存),将它们放入HashSet h
A
读取所有实体,计算A\h
,这应该非常快,然后将A\h
插入B
,可能使用批量插入库。这里的关键是避免为A
中的每个元素进行数据库查找。