Skip to content

Instantly share code, notes, and snippets.

@joshbartley
Last active August 29, 2015 14:07
Show Gist options
  • Save joshbartley/400bb4513848ef85bf3a to your computer and use it in GitHub Desktop.
Save joshbartley/400bb4513848ef85bf3a to your computer and use it in GitHub Desktop.
Entity Framework Sequence Key Support
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity.Core.EntityClient;
using System.Data.Entity.Core.Metadata.Edm;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Core.Objects.DataClasses;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
namespace Repository
{
public partial class EfEntities
{
public EfEntities(string connectionString)
: base(connectionString)
{
}
public static Entities NewEntities()
{
return new Entities(GenerateEFConnection());
}
public static string GenerateEFConnection()
{
return new EntityConnectionStringBuilder
{
Metadata = "res://*/",
ProviderConnectionString = YOUR_CONNECTION_STRING,
Provider = "System.Data.SqlClient"
}.ToString();
}
public override int SaveChanges()
{
//Figure How many keys of each type we need, so we can grab them from db all at once
//Request keys from DB
var keys = GenerateKeys(this.ChangeTracker.Entries().LongCount(e => e.Entity is ISequenceBase && e.State == EntityState.Added));
ObjectContext objectContext = ((IObjectContextAdapter)this).ObjectContext;
var w = objectContext.MetadataWorkspace;
foreach (var entry in this.ChangeTracker.Entries().Where(e => e.Entity is ISequenceBase
&& e.State == EntityState.Added))
{
var entityType = entry.Entity.GetType();
var entityName = entityType.Name;
var wKey = w.GetEntityContainer(objectContext.DefaultContainerName, DataSpace.CSpace)
.BaseEntitySets.First(meta => meta.ElementType.Name == entityName)
.ElementType.KeyMembers.Select(k => k.Name).FirstOrDefault();
if (!string.IsNullOrEmpty(wKey))
entry.Property(wKey).CurrentValue = keys.Dequeue();
}
int result = base.SaveChanges();
return result;
}
private Queue<long> GenerateKeys(long sequenceKeysRequested)
{
Queue<long> sequences = null;
if (sequenceKeysRequested > 0)
{
var paramSequenceObject = new SqlParameter("@sequence_name", SqlDbType.VarChar) {Value = "{Your Sequence Object}"};
var paramRangeSize = new SqlParameter("@range_size", SqlDbType.Int) {Value = sequenceKeysRequested};
var paramRangeFirstValue = new SqlParameter("@range_first_value", SqlDbType.Variant){ Direction = ParameterDirection.Output};
var paramRangeLastValue = new SqlParameter("@range_last_value", SqlDbType.Variant) { Direction = ParameterDirection.Output };
this.Database.ExecuteSqlCommand("exec sys.sp_sequence_get_range @sequence_name, @range_size, @range_first_value OUTPUT, @range_last_value OUTPUT", paramSequenceObject, paramRangeSize, paramRangeFirstValue, paramRangeLastValue);
sequences = new Queue<long>((int) ((long) paramRangeLastValue.Value - (long) paramRangeFirstValue.Value)+1);
for (long i = (long) paramRangeFirstValue.Value; i <= (long) paramRangeLastValue.Value; i++)
{
sequences.Enqueue(i);
}
}
return sequences;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment