Created
August 16, 2012 17:21
-
-
Save ferventcoder/3371820 to your computer and use it in GitHub Desktop.
Db First Generic Repository with DbFirst Model First - allows use of stored procedures transparently - it's no coincidence that the IRepository is the same as code first implements
This file contains 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
public class EntityFrameworkDatabaseFirstRepository : IRepository | |
{ | |
private readonly IDatabaseFirstDataContext _dataContext; | |
/// <summary> | |
/// Gets the data context. | |
/// </summary> | |
protected IDatabaseFirstDataContext DataContext | |
{ | |
get | |
{ | |
return _dataContext; | |
} | |
} | |
/// <summary> | |
/// Initializes a new instance of the <see cref="EntityFrameworkDatabaseFirstRepository"/> class. | |
/// </summary> | |
/// <param name="dataContext">The data context.</param> | |
public EntityFrameworkDatabaseFirstRepository(IDatabaseFirstDataContext dataContext) | |
{ | |
_dataContext = dataContext; | |
} | |
/// <summary> | |
/// Commits the changes. | |
/// </summary> | |
public void CommitChanges() | |
{ | |
this.Log().Debug(() => "EF is saving all changes to the repository"); | |
_dataContext.SaveChanges(); | |
} | |
/// <summary> | |
/// Gets the specified key. | |
/// </summary> | |
/// <typeparam name="T"> A class that implements <see cref="IDomain" /> with a default constructor </typeparam> | |
/// <param name="key">The key.</param> | |
/// <returns></returns> | |
public T Get<T>(params object[] key) where T : class, IDomain, new() | |
{ | |
this.Log().Debug(() => "EF is searching for '{0} ({1})'".FormatWith(typeof(T).Name, key)); | |
var set = _dataContext.Set<T>(); | |
//http://stackoverflow.com/questions/5794902/generic-getbyid-for-complex-pk | |
var keyNames = set.EntitySet.ElementType.KeyMembers.Select(k => k.Name).ToArray(); | |
if (key.Length != keyNames.Length) | |
{ | |
throw new ArgumentException("Invalid number of key members"); | |
} | |
var keyPairs = keyNames.Zip(key, (keyName, keyValue) => new KeyValuePair<string, object>(keyName, keyValue)); | |
var entityKey = new EntityKey(set.EntitySet.Name, keyPairs); | |
return (T)_dataContext.GetObjectByKey(entityKey); | |
} | |
/// <summary> | |
/// Gets all instances of <see cref="T"/> . Can be used with a linq query to limit results | |
/// </summary> | |
/// <typeparam name="T">A class that implements <see cref="IDomain"/> with a default constructor</typeparam> | |
/// <returns> | |
/// A list of <see cref="T"/> | |
/// </returns> | |
public IQueryable<T> GetAll<T>() where T : class, IDomain, new() | |
{ | |
this.Log().Debug(() => "EF is performing a query for '{0}'".FormatWith(typeof(T).Name)); | |
return _dataContext.Set<T>(); | |
} | |
/// <summary> | |
/// Inserts the specified entity instance of <see cref="T"/> on commit. | |
/// </summary> | |
/// <typeparam name="T">A class that implements <see cref="IDomain"/> with a default constructor</typeparam> | |
/// <param name="entity">The entity.</param> | |
public void InsertOnCommit<T>(T entity) where T : class, IDomain, new() | |
{ | |
//entity.SetInsertProperties(); | |
this.Log().Debug(() => "EF is inserting a '{0}'".FormatWith(typeof(T).Name)); | |
_dataContext.Set<T>().AddObject(entity); | |
} | |
/// <summary> | |
/// Deletes the specified entity instance of <see cref="T"/> on commit. | |
/// </summary> | |
/// <typeparam name="T">A class that implements <see cref="IDomain"/> with a default constructor</typeparam> | |
/// <param name="entity">The entity.</param> | |
public void DeleteOnCommit<T>(T entity) where T : class, IDomain, new() | |
{ | |
this.Log().Debug(() => "EF is deleting a '{0}'".FormatWith(typeof(T).Name)); | |
_dataContext.Set<T>().DeleteObject(entity); | |
} | |
} |
This file contains 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
//Name and namespace is an exact match to the EDMX Object Context implementation | |
public partial class DatabaseFirstObjectContext : ObjectContext, IDatabaseFirstDataContext | |
{ | |
public ObjectSet<TEntity> Set<TEntity>() where TEntity : class | |
{ | |
return CreateObjectSet<TEntity>(); | |
} | |
public new int SaveChanges() | |
{ | |
foreach (ObjectStateEntry obj in ObjectStateManager.GetObjectStateEntries(EntityState.Added).OrEmptyListIfNull()) | |
{ | |
var entity = (IDomain) obj.Entity; | |
if (entity != null) | |
{ | |
entity.SetReadyForInsert(); | |
} | |
} | |
foreach (ObjectStateEntry obj in ObjectStateManager.GetObjectStateEntries(EntityState.Modified).OrEmptyListIfNull()) | |
{ | |
var entity = (IDomain) obj.Entity; | |
if (entity != null) | |
{ | |
entity.SetReadyForUpdate(); | |
} | |
} | |
return base.SaveChanges(SaveOptions.AcceptAllChangesAfterSave); | |
} | |
} |
This file contains 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
// name here is an exact match to a class in the EDMX model | |
// repeat this pattern as many times as is necessary. | |
// for an ID that is multiple parts (composite), create a class and put those in it, then have the Id return those back and set the items in the model when setting | |
public partial class ClassThatIsInEDMXModel : IDomain<int> | |
{ | |
public int Id | |
{ | |
get { return ModelsID; } | |
set { ModelsID = value; } | |
} | |
public void SetInsertProperties() {} | |
public void SetUpdateProperties() {} | |
} |
This file contains 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
public interface IDomain | |
{ | |
DateTime CreateDate { get; set; } | |
int CreateUserId { get; set; } | |
DateTime UpdateDate { get; set; } | |
int UpdateUserId { get; set; } | |
void SetInsertProperties(); | |
void SetUpdateProperties(); | |
} | |
/// <summary> | |
/// For situations where you need access to the key | |
/// </summary> | |
/// <typeparam name="TKeyType">The type of the key.</typeparam> | |
public interface IDomain<TKeyType> : IDomain | |
{ | |
/// <summary> | |
/// Gets or sets the id. | |
/// </summary> | |
/// <value> | |
/// The id. | |
/// </value> | |
TKeyType Id { get; set; } | |
} |
This file contains 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
public static class IDomainExtensions | |
{ | |
public static void SetReadyForInsert(this IDomain domain) | |
{ | |
domain.SetInsertProperties(); | |
domain.CreateDate = DateTime.Now; | |
domain.UpdateDate = DateTime.Now; | |
domain.CreateUserId = ApplicationParameters.GetCurrentUserId(); | |
domain.UpdateUserId = ApplicationParameters.GetCurrentUserId(); | |
} | |
public static void SetReadyForUpdate(this IDomain domain) | |
{ | |
domain.SetUpdateProperties(); | |
domain.UpdateDate = DateTime.Now; | |
domain.UpdateUserId = ApplicationParameters.GetCurrentUserId(); | |
} | |
} |
This file contains 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
/// <summary> | |
/// The data context used work with the database. This interface repeats items already in the DbContext or ObjectContext | |
/// </summary> | |
public interface IDataContext | |
{ | |
/// <summary> | |
/// Saves the changes. | |
/// </summary> | |
int SaveChanges(); | |
} | |
public interface IDatabaseFirstDataContext : IDataContext | |
{ | |
/// <summary> | |
/// Grabs a set, can be used with linq queries to limit results | |
/// </summary> | |
/// <typeparam name="TEntity">The type of the entity.</typeparam> | |
/// <returns></returns> | |
ObjectSet<TEntity> Set<TEntity>() where TEntity : class; | |
/// <summary> | |
/// Gets the object by key. | |
/// </summary> | |
/// <param name="key">The key.</param> | |
/// <returns></returns> | |
object GetObjectByKey(EntityKey key); | |
} | |
/// <summary> | |
/// The data context used work with the database. This interface repeats items already in the DbContext | |
/// </summary> | |
public interface ICodeFirstDataContext : IDataContext | |
{ | |
/// <summary> | |
/// Grabs a set, can be used with linq queries to limit results | |
/// </summary> | |
/// <typeparam name="TEntity">The type of the entity.</typeparam> | |
/// <returns></returns> | |
DbSet<TEntity> Set<TEntity>() where TEntity : class; | |
/// <summary> | |
/// Gets the database. | |
/// </summary> | |
Database Database { get; } | |
} |
This file contains 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
/// <summary> | |
/// The repository for working with the database. | |
/// </summary> | |
public interface IRepository | |
{ | |
/// <summary> | |
/// Commits the changes. | |
/// </summary> | |
void CommitChanges(); | |
/// <summary> | |
/// Gets an instance of <see cref="T" /> with the specified key. | |
/// </summary> | |
/// <typeparam name="T"> A class that implements <see cref="IDomain" /> with a default constructor </typeparam> | |
/// <param name="key"> The key. </param> | |
/// <returns> </returns> | |
T Get<T>(params object[] key) where T : class, IDomain, new(); | |
/// <summary> | |
/// Gets all instances of <see cref="T" /> . Can be used with a linq query to limit results | |
/// </summary> | |
/// <typeparam name="T"> A class that implements <see cref="IDomain" /> with a default constructor </typeparam> | |
/// <returns> A list of <see cref="T" /> </returns> | |
IQueryable<T> GetAll<T>() where T : class, IDomain, new(); | |
/// <summary> | |
/// Inserts the specified entity instance of <see cref="T" /> on commit. | |
/// </summary> | |
/// <typeparam name="T"> A class that implements <see cref="IDomain" /> with a default constructor </typeparam> | |
/// <param name="entity"> The entity. </param> | |
/// <returns> The Id of the inserted item </returns> | |
void InsertOnCommit<T>(T entity) where T : class, IDomain, new(); | |
/// <summary> | |
/// Deletes the specified entity instance of <see cref="T" /> on commit. | |
/// </summary> | |
/// <typeparam name="T"> A class that implements <see cref="IDomain" /> with a default constructor </typeparam> | |
/// <param name="entity"> The entity. </param> | |
void DeleteOnCommit<T>(T entity) where T : class, IDomain, new(); | |
} |
This file contains 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
/// <summary> | |
/// The entity framework repository | |
/// </summary> | |
public class EntityFrameworkCodeFirstRepository : IRepository | |
{ | |
private readonly ICodeFirstDataContext _dataContext; | |
/// <summary> | |
/// Gets the data context. | |
/// </summary> | |
protected ICodeFirstDataContext DataContext | |
{ | |
get { return _dataContext; } | |
} | |
/// <summary> | |
/// Initializes a new instance of the <see cref="EntityFrameworkCodeFirstRepository" /> class. | |
/// </summary> | |
/// <param name="dataContext"> The data context. </param> | |
public EntityFrameworkCodeFirstRepository(ICodeFirstDataContext dataContext) | |
{ | |
_dataContext = dataContext; | |
} | |
/// <summary> | |
/// Commits the changes. | |
/// </summary> | |
public virtual void CommitChanges() | |
{ | |
this.Log().Debug(() => "EF is saving all changes to the repository"); | |
_dataContext.SaveChanges(); | |
} | |
/// <summary> | |
/// Gets an instance of <see cref="T" /> with the specified key. | |
/// </summary> | |
/// <typeparam name="T"> A class that implements <see cref="IDomain" /> with a default constructor </typeparam> | |
/// <param name="key"> The key. </param> | |
/// <returns> </returns> | |
public virtual T Get<T>(params object[] key) where T : class, IDomain, new() | |
{ | |
this.Log().Debug(() => "EF is searching for '{0} ({1})'".FormatWith(typeof (T).Name, key)); | |
return _dataContext.Set<T>().Find(key); | |
} | |
/// <summary> | |
/// Gets all instances of <see cref="T" /> . Can be used with a linq query to limit results | |
/// </summary> | |
/// <typeparam name="T"> A class that implements <see cref="IDomain" /> with a default constructor </typeparam> | |
/// <returns> A list of <see cref="T" /> </returns> | |
public virtual IQueryable<T> GetAll<T>() where T : class, IDomain, new() | |
{ | |
this.Log().Debug(() => "EF is performing a query for '{0}'".FormatWith(typeof (T).Name)); | |
return _dataContext.Set<T>(); | |
} | |
/// <summary> | |
/// Inserts the specified entity instance of <see cref="T" /> on commit. | |
/// </summary> | |
/// <typeparam name="T"> A class that implements <see cref="IDomain" /> with a default constructor </typeparam> | |
/// <param name="entity"> The entity. </param> | |
/// <returns> The Id of the inserted item </returns> | |
public virtual void InsertOnCommit<T>(T entity) where T : class, IDomain, new() | |
{ | |
//entity.SetInsertProperties(); | |
this.Log().Debug(() => "EF is inserting a '{0}'".FormatWith(typeof (T).Name)); | |
_dataContext.Set<T>().Add(entity); | |
} | |
/// <summary> | |
/// Deletes the specified entity instance of <see cref="T" /> on commit. | |
/// </summary> | |
/// <typeparam name="T"> A class that implements <see cref="IDomain" /> with a default constructor </typeparam> | |
/// <param name="entity"> The entity. </param> | |
public virtual void DeleteOnCommit<T>(T entity) where T : class, IDomain, new() | |
{ | |
//this.Log().Debug(() => "EF is deleting '{0} ({1})'".FormatWith(typeof (T).Name, entity.GetKey())); | |
this.Log().Debug(() => "EF is deleting a '{0}'".FormatWith(typeof (T).Name)); | |
_dataContext.Set<T>().Remove(entity); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment