forked from SharpRepository/SharpRepository
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Replaced Ef5Repository with EfRepository
Now that EF6 is out the version specific repository name isn't great moving forward. We originally had an EfRepository that was for EF4.1 and when they changed from ObjectContext to DbContext we needed to have 2 versions so we started Ef5Repository. Now it seems EF is using the same NuGet package with a new version so EfRepository will just require EntityFramework 5.0 or greater.
- Loading branch information
Jeff Treuting
committed
Oct 23, 2013
1 parent
74a6349
commit 5beed08
Showing
85 changed files
with
221,381 additions
and
74 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<configuration> | ||
<configSections> | ||
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> | ||
|
||
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --></configSections> | ||
<entityFramework> | ||
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" /> | ||
<providers> | ||
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> | ||
</providers> | ||
</entityFramework> | ||
<startup> | ||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" /> | ||
</startup> | ||
</configuration> |
275 changes: 275 additions & 0 deletions
275
SharpRepository.EfRepository/EfCompoundKeyRepositoryBase.cs
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,275 @@ | ||
using System; | ||
using System.Data; | ||
using System.Data.Entity; | ||
using System.Linq; | ||
using SharpRepository.Repository; | ||
using SharpRepository.Repository.Caching; | ||
using SharpRepository.Repository.FetchStrategies; | ||
|
||
namespace SharpRepository.EfRepository | ||
{ | ||
public class EfCompoundKeyRepositoryBase<T> : LinqCompoundKeyRepositoryBase<T> where T : class, new() | ||
{ | ||
protected IDbSet<T> DbSet { get; private set; } | ||
protected DbContext Context { get; private set; } | ||
|
||
internal EfCompoundKeyRepositoryBase(DbContext dbContext, ICompoundKeyCachingStrategy<T> cachingStrategy = null) | ||
: base(cachingStrategy) | ||
{ | ||
Initialize(dbContext); | ||
} | ||
|
||
private void Initialize(DbContext dbContext) | ||
{ | ||
Context = dbContext; | ||
DbSet = Context.Set<T>(); | ||
} | ||
|
||
protected override void AddItem(T entity) | ||
{ | ||
// no generating primary keys | ||
DbSet.Add(entity); | ||
} | ||
|
||
protected override void DeleteItem(T entity) | ||
{ | ||
DbSet.Remove(entity); | ||
} | ||
|
||
protected override void UpdateItem(T entity) | ||
{ | ||
var entry = Context.Entry<T>(entity); | ||
|
||
if (entry.State == EntityState.Detached) | ||
{ | ||
object[] keys; | ||
|
||
if (GetPrimaryKeys(entity, out keys)) | ||
{ | ||
// check to see if this item is already attached | ||
// if it is then we need to copy the values to the attached value instead of changing the State to modified since it will throw a duplicate key exception | ||
// specifically: "An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key." | ||
var attachedEntity = Context.Set<T>().Find(keys); | ||
if (attachedEntity != null) | ||
{ | ||
Context.Entry(attachedEntity).CurrentValues.SetValues(entity); | ||
|
||
return; | ||
} | ||
} | ||
} | ||
|
||
// default | ||
entry.State = EntityState.Modified; | ||
} | ||
|
||
protected override void SaveChanges() | ||
{ | ||
Context.SaveChanges(); | ||
} | ||
|
||
protected override IQueryable<T> BaseQuery(IFetchStrategy<T> fetchStrategy = null) | ||
{ | ||
var query = DbSet.AsQueryable(); | ||
return fetchStrategy == null ? query : fetchStrategy.IncludePaths.Aggregate(query, (current, path) => current.Include(path)); | ||
} | ||
|
||
// we override the implementation fro LinqBaseRepository becausee this is built in and doesn't need to find the key column and do dynamic expressions, etc. | ||
protected override T GetQuery(params object[] keys) | ||
{ | ||
return DbSet.Find(keys); | ||
} | ||
|
||
public override void Dispose() | ||
{ | ||
Dispose(true); | ||
GC.SuppressFinalize(this); | ||
} | ||
|
||
protected virtual void Dispose(bool disposing) | ||
{ | ||
if (!disposing) return; | ||
if (Context == null) return; | ||
|
||
Context.Dispose(); | ||
Context = null; | ||
} | ||
} | ||
|
||
public class EfCompoundKeyRepositoryBase<T, TKey, TKey2> : LinqCompoundKeyRepositoryBase<T, TKey, TKey2> where T : class, new() | ||
{ | ||
protected IDbSet<T> DbSet { get; private set; } | ||
protected DbContext Context { get; private set; } | ||
|
||
internal EfCompoundKeyRepositoryBase(DbContext dbContext, ICompoundKeyCachingStrategy<T, TKey, TKey2> cachingStrategy = null) | ||
: base(cachingStrategy) | ||
{ | ||
Initialize(dbContext); | ||
} | ||
|
||
private void Initialize(DbContext dbContext) | ||
{ | ||
Context = dbContext; | ||
DbSet = Context.Set<T>(); | ||
} | ||
|
||
protected override void AddItem(T entity) | ||
{ | ||
DbSet.Add(entity); | ||
} | ||
|
||
protected override void DeleteItem(T entity) | ||
{ | ||
DbSet.Remove(entity); | ||
} | ||
|
||
protected override void UpdateItem(T entity) | ||
{ | ||
var entry = Context.Entry<T>(entity); | ||
|
||
if (entry.State == EntityState.Detached) | ||
{ | ||
TKey key; | ||
TKey2 key2; | ||
|
||
if (GetPrimaryKey(entity, out key, out key2)) | ||
{ | ||
// check to see if this item is already attached | ||
// if it is then we need to copy the values to the attached value instead of changing the State to modified since it will throw a duplicate key exception | ||
// specifically: "An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key." | ||
var attachedEntity = Context.Set<T>().Find(key, key2); | ||
if (attachedEntity != null) | ||
{ | ||
Context.Entry(attachedEntity).CurrentValues.SetValues(entity); | ||
|
||
return; | ||
} | ||
} | ||
} | ||
|
||
// default | ||
entry.State = EntityState.Modified; | ||
} | ||
|
||
protected override void SaveChanges() | ||
{ | ||
Context.SaveChanges(); | ||
} | ||
|
||
protected override IQueryable<T> BaseQuery(IFetchStrategy<T> fetchStrategy = null) | ||
{ | ||
var query = DbSet.AsQueryable(); | ||
return fetchStrategy == null ? query : fetchStrategy.IncludePaths.Aggregate(query, (current, path) => current.Include(path)); | ||
} | ||
|
||
// we override the implementation fro LinqBaseRepository becausee this is built in and doesn't need to find the key column and do dynamic expressions, etc. | ||
protected override T GetQuery(TKey key, TKey2 key2) | ||
{ | ||
return DbSet.Find(key, key2); | ||
} | ||
|
||
public override void Dispose() | ||
{ | ||
Dispose(true); | ||
GC.SuppressFinalize(this); | ||
} | ||
|
||
protected virtual void Dispose(bool disposing) | ||
{ | ||
if (!disposing) return; | ||
if (Context == null) return; | ||
|
||
Context.Dispose(); | ||
Context = null; | ||
} | ||
} | ||
|
||
public class EfCompoundKeyRepositoryBase<T, TKey, TKey2, TKey3> : LinqCompoundKeyRepositoryBase<T, TKey, TKey2, TKey3> where T : class, new() | ||
{ | ||
protected IDbSet<T> DbSet { get; private set; } | ||
protected DbContext Context { get; private set; } | ||
|
||
internal EfCompoundKeyRepositoryBase(DbContext dbContext, ICompoundKeyCachingStrategy<T, TKey, TKey2, TKey3> cachingStrategy = null) | ||
: base(cachingStrategy) | ||
{ | ||
Initialize(dbContext); | ||
} | ||
|
||
private void Initialize(DbContext dbContext) | ||
{ | ||
Context = dbContext; | ||
DbSet = Context.Set<T>(); | ||
} | ||
|
||
protected override void AddItem(T entity) | ||
{ | ||
DbSet.Add(entity); | ||
} | ||
|
||
protected override void DeleteItem(T entity) | ||
{ | ||
DbSet.Remove(entity); | ||
} | ||
|
||
protected override void UpdateItem(T entity) | ||
{ | ||
var entry = Context.Entry<T>(entity); | ||
|
||
if (entry.State == EntityState.Detached) | ||
{ | ||
TKey key; | ||
TKey2 key2; | ||
TKey3 key3; | ||
|
||
if (GetPrimaryKey(entity, out key, out key2, out key3)) | ||
{ | ||
// check to see if this item is already attached | ||
// if it is then we need to copy the values to the attached value instead of changing the State to modified since it will throw a duplicate key exception | ||
// specifically: "An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key." | ||
var attachedEntity = Context.Set<T>().Find(key, key2, key3); | ||
if (attachedEntity != null) | ||
{ | ||
Context.Entry(attachedEntity).CurrentValues.SetValues(entity); | ||
|
||
return; | ||
} | ||
} | ||
} | ||
|
||
// default | ||
entry.State = EntityState.Modified; | ||
} | ||
|
||
protected override void SaveChanges() | ||
{ | ||
Context.SaveChanges(); | ||
} | ||
|
||
protected override IQueryable<T> BaseQuery(IFetchStrategy<T> fetchStrategy = null) | ||
{ | ||
var query = DbSet.AsQueryable(); | ||
return fetchStrategy == null ? query : fetchStrategy.IncludePaths.Aggregate(query, (current, path) => current.Include(path)); | ||
} | ||
|
||
// we override the implementation fro LinqBaseRepository becausee this is built in and doesn't need to find the key column and do dynamic expressions, etc. | ||
protected override T GetQuery(TKey key, TKey2 key2, TKey3 key3) | ||
{ | ||
return DbSet.Find(key, key2, key3); | ||
} | ||
|
||
public override void Dispose() | ||
{ | ||
Dispose(true); | ||
GC.SuppressFinalize(this); | ||
} | ||
|
||
protected virtual void Dispose(bool disposing) | ||
{ | ||
if (!disposing) return; | ||
if (Context == null) return; | ||
|
||
Context.Dispose(); | ||
Context = null; | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
using System; | ||
using System.Configuration; | ||
using System.Data.Entity; | ||
using SharpRepository.Repository; | ||
using SharpRepository.Repository.Configuration; | ||
using SharpRepository.Repository.Ioc; | ||
|
||
namespace SharpRepository.EfRepository | ||
{ | ||
public class EfConfigRepositoryFactory : ConfigRepositoryFactory | ||
{ | ||
public EfConfigRepositoryFactory(IRepositoryConfiguration config) | ||
: base(config) | ||
{ | ||
} | ||
|
||
public override IRepository<T> GetInstance<T>() | ||
{ | ||
return new EfRepository<T>(GetDbContext()); | ||
} | ||
|
||
public override IRepository<T, TKey> GetInstance<T, TKey>() | ||
{ | ||
return new EfRepository<T, TKey>(GetDbContext()); | ||
} | ||
|
||
public override ICompoundKeyRepository<T, TKey, TKey2> GetInstance<T, TKey, TKey2>() | ||
{ | ||
return new EfRepository<T, TKey, TKey2>(GetDbContext()); | ||
} | ||
|
||
private DbContext GetDbContext() | ||
{ | ||
var connectionString = RepositoryConfiguration["connectionString"]; | ||
|
||
// check for required parameters | ||
if (RepositoryDependencyResolver.Current == null && String.IsNullOrEmpty(connectionString)) | ||
{ | ||
throw new ConfigurationErrorsException("The connectionString attribute is required in order to use the Ef5Repository via the configuration file, unless you set the RepositoryDependencyResolver to use an Ioc container."); | ||
} | ||
|
||
Type dbContextType = null; | ||
|
||
var tmpDbContextType = RepositoryConfiguration["dbContextType"]; | ||
if (!String.IsNullOrEmpty(tmpDbContextType)) | ||
{ | ||
dbContextType = Type.GetType(tmpDbContextType); | ||
} | ||
|
||
// TODO: look at dbContextType (from Enyim.Caching configuration bits) and how it caches, see about implementing cache or expanding FastActivator to take parameters | ||
DbContext dbContext = null; | ||
|
||
// if there is an IOC dependency resolver configured then use that one to get the DbContext, this will allow sharing of context across multiple repositories if the IOC is configured that way | ||
if (RepositoryDependencyResolver.Current != null) | ||
{ | ||
dbContext = dbContextType == null | ||
? RepositoryDependencyResolver.Current.Resolve<DbContext>() | ||
: (DbContext)RepositoryDependencyResolver.Current.Resolve(dbContextType); | ||
|
||
// if the Ioc container doesn't throw an error but still returns null we need to alert the consumer | ||
if (dbContext == null) | ||
{ | ||
throw new RepositoryDependencyResolverException(typeof(DbContext)); | ||
} | ||
} | ||
else // the default way of getting a DbContext if there is no Ioc container setup | ||
{ | ||
dbContext = dbContextType == null | ||
? new DbContext(connectionString) | ||
: (DbContext)Activator.CreateInstance(dbContextType, connectionString); | ||
} | ||
|
||
return dbContext; | ||
} | ||
} | ||
} |
Oops, something went wrong.