Last active
August 29, 2015 14:07
-
-
Save joshbartley/400bb4513848ef85bf3a to your computer and use it in GitHub Desktop.
Entity Framework Sequence Key Support
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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