Generating Repositories for the database entities could be a big repetitive task with similar code. The project at https://efrepository.codeplex.com solves the problem by generating a T4 Template for the edmx model. The T4 Template then generates the required repositories, the Unit of Work pattern, and also provides a factory for the repositories.
The template, however, generates code for the ObjectContext approach.
I have modified the template, so that it can be used with the EntityFramework 5.0 and above to generate the relevant repositories.
Here is the Template below.
//==========================================================================
<#@ template language="C#" debug="true" hostspecific="true"#>
<#@ include file="EF.Utility.CS.ttinclude"#>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Diagnostics" #>
<#@ output extension=".cs"#>
<#
// This needs to be set to the .edmx file that you want to process.
string edmxFile = FindEDMXFileName(); // @"Model1.edmx";
CodeGenerationTools code = new CodeGenerationTools(this);
MetadataLoader loader = new MetadataLoader(this);
MetadataTools ef = new MetadataTools(this);
#>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace <#= code.VsNamespaceSuggestion() #>
{
public interface IRepository
{
IUnitOfWork UnitOfWork { get; set; }
IQueryable All();
IQueryable Where(Func expression);
void Add(T entity);
void Delete(T entity);
}
}<#
EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(edmxFile);
EntityContainer container = ItemCollection.GetItems().FirstOrDefault();
EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);
foreach (EntityType entity in ItemCollection.GetItems().OrderBy(e => e.Name))
{;
if(!DoesFileExist(entity.Name + "Repository.cs"))
{
fileManager.StartNewFile(entity.Name + "Repository.cs");
#>using System;
using System.Linq;
using System.Collections.Generic;
namespace <#= code.VsNamespaceSuggestion() #>
{
<#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=code.Escape(entity)#>Repository : EFRepository<<#=code.Escape(entity)#>>, I<#=code.Escape(entity)#>Repository
{
}
<#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#> interface I<#=code.Escape(entity)#>Repository
{
}
}<#
}
else
{
fileManager.StartNewFile(entity.Name + "Repository.cs");
this.Write(OutputFile(entity.Name + "Repository.cs"));
}
}
fileManager.StartNewFile("IUnitOfWork.cs");
#>using System.Data.Objects;
using System.Data.Entity;
namespace <#= code.VsNamespaceSuggestion() #>
{
public interface IUnitOfWork
{
DbContext Context { get; set; }
void Commit();
bool LazyLoadingEnabled { get; set; }
bool ProxyCreationEnabled { get; set; }
string ConnectionString { get; set; }
}
}<# fileManager.StartNewFile("RepositoryIQueryableExtensions.cs");
#>using System.Data.Objects;
using System.Linq;
namespace <#= code.VsNamespaceSuggestion() #>
{
public static class RepositoryIQueryableExtensions
{
public static IQueryable Include
(this IQueryable source, string path)
{
var objectQuery = source as ObjectQuery;
if (objectQuery != null)
{
return objectQuery.Include(path);
}
return source;
}
}
}<# fileManager.StartNewFile("EFRepository.cs");
#>using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
namespace <#= code.VsNamespaceSuggestion() #>
{
public class EFRepository : IRepository where T : class
{
public IUnitOfWork UnitOfWork { get; set; }
private DbSet _dbSet;
private DbSet DbSet
{
get
{
if (_dbSet == null)
{
_dbSet = UnitOfWork.Context.Set();
}
return _dbSet;
}
}
public virtual IQueryable All()
{
return DbSet.AsQueryable();
}
public IQueryable Where(Func expression)
{
return DbSet.Where(expression).AsQueryable();
}
public void Add(T entity)
{
DbSet.Add(entity);
}
public void Delete(T entity)
{
DbSet.Remove(entity);
}
}
}<#fileManager.StartNewFile("EFUnitOfWork.cs");
#>using System.Data.Objects;
using System.Data.Entity;
namespace <#= code.VsNamespaceSuggestion() #>
{
public class EFUnitOfWork : IUnitOfWork
{
public DbContext Context { get; set; }
public EFUnitOfWork()
{
Context = new <#=code.Escape(container)#>();
}
public void Commit()
{
Context.SaveChanges();
}
public bool LazyLoadingEnabled
{
get { return true; }
set { }
}
public bool ProxyCreationEnabled
{
get { return true; }
set { }
}
public string ConnectionString
{
get { return Context.Database.Connection.ConnectionString; }
set { Context.Database.Connection.ConnectionString = value; }
}
}
}
<#fileManager.StartNewFile("RepositoryHelper.cs");
#>
namespace <#= code.VsNamespaceSuggestion() #>
{
public static class RepositoryHelper
{
public static IUnitOfWork GetUnitOfWork()
{
return new EFUnitOfWork();
}
<# foreach (EntityType entity in ItemCollection.GetItems().OrderBy(e => e.Name))
{; #>
public static <#=code.Escape(entity)#>Repository Get<#=code.Escape(entity)#>Repository()
{
return new <#=code.Escape(entity)#>Repository();
}
public static <#=code.Escape(entity)#>Repository Get<#=code.Escape(entity)#>Repository(IUnitOfWork unitOfWork)
{
var repository = new <#=code.Escape(entity)#>Repository();
repository.UnitOfWork = unitOfWork;
return repository;
}
<# } #>
}
}<# fileManager.Process();
#>
<#+
bool DoesFileExist(string filename)
{
return File.Exists(Path.Combine(GetCurrentDirectory(),filename));
}
string OutputFile(string filename)
{
using(StreamReader sr = new StreamReader(Path.Combine(GetCurrentDirectory(),filename)))
{
string contents = sr.ReadToEnd();
return contents;
}
}
string GetCurrentDirectory()
{
string executingDirectoryName = "";
string stackTraceFileName = new StackTrace(true).GetFrame(0).GetFileName();
if (String.IsNullOrEmpty(stackTraceFileName))
{
throw new ArgumentException("No value was specified for the 'directoryName' configuration parameter" +
", and we could not figure out the file name from the stack trace (most likely because of running " +
"the template with debug='False' specified in the <\u0023@ template \u0023> directive.");
}
else
{
executingDirectoryName = Path.GetDirectoryName(stackTraceFileName);
}
return executingDirectoryName;
}
string FindEDMXFileName()
{
string edmxFile = "";
string[] entityFrameworkFiles = Directory.GetFiles(GetCurrentDirectory(), "*.edmx");
if(entityFrameworkFiles.Length > 0)
edmxFile = entityFrameworkFiles[0];
return edmxFile;
}
#>
No comments:
Post a Comment