Skip to content

Commit

Permalink
Replaced Ef5Repository with EfRepository
Browse files Browse the repository at this point in the history
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
Show file tree
Hide file tree
Showing 85 changed files with 221,381 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,6 @@
<Project>{06111314-669B-4E35-A0B9-AF67FA3F0FFD}</Project>
<Name>SharpRepository.Caching.Memcached</Name>
</ProjectReference>
<ProjectReference Include="..\SharpRepository.Ef5Repository\SharpRepository.Ef5Repository.csproj">
<Project>{7ACC7E0F-2EB9-45E1-8841-A00A40BCF0B5}</Project>
<Name>SharpRepository.Ef5Repository</Name>
</ProjectReference>
<ProjectReference Include="..\SharpRepository.InMemoryRepository\SharpRepository.InMemoryRepository.csproj">
<Project>{13ad3fca-4c9d-4674-b786-f30843638d3b}</Project>
<Name>SharpRepository.InMemoryRepository</Name>
Expand Down
16 changes: 16 additions & 0 deletions SharpRepository.EfRepository/App.config
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 SharpRepository.EfRepository/EfCompoundKeyRepositoryBase.cs
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;
}
}
}
76 changes: 76 additions & 0 deletions SharpRepository.EfRepository/EfConfigRepositoryFactory.cs
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;
}
}
}
Loading

0 comments on commit 5beed08

Please sign in to comment.