UPDATE
Sorry I missed that the question was tagged EF4. This will only work with new version where EF changed their mapping API. I leave it here because the same thing can be done with old api's too, I can find the code for doing that after work
Disclaimer: I'm the author of EFUtilities
EFUtilities https://github.com/MikaelEliasson/EntityFramework.Utilities supports Bulk update now. Out of the box it doesn't let you do the merge part. If you have a way of knowing which entities to insert and which to update you could issue one insert https://github.com/MikaelEliasson/EntityFramework.Utilities#batch-insert-entities and one update https://github.com/MikaelEliasson/EntityFramework.Utilities#batch-update-entities
If you really need the merge It can help you with building the table. You can get access to the metadata I'm using internally by this code.
using (var db = new Context())
{
var mapping = EfMappingFactory.GetMappingsForContext(db);
var commentMapping = mapping.TypeMappings[typeof(Comment)];
}
The typeMapping contain all the information I use for dynamically building my temp tables for the bulk update. For some reason I made that code private but here is the method that generates the sql for the table. All info is available on the 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;
}