Einheit von Arbeit mit dem Repository-Pattern MVC 5 & EF-6
Ich zusammen eine Probe, wie ich mich mit der Einheit von Arbeit & Repository-pattern, basierend auf mein Verständnis. Kann jemand bitte lassen Sie mich wissen, wenn ich die Umsetzung dieses der richtige Weg? Wenn ich nicht bin, wie kann ich es verbessern?
Vielen Dank im Voraus, es ist viel geschätzt.
Habe ich ein EF-Modell mit zwei Entitäten: Thema und Unterthema. Das EF-Modell genannt wird CommonGood.
Einheit der Arbeit:
///<summary>
///Implementation of a UnitOfWork class
///</summary>
public static class UnitOfWork
{
///<summary>
///Gets the default context
///</summary>
///<returns>A new instance of the default context</returns>
public static CommonGoodEntities GetContext()
{
return new CommonGoodEntities();
}
}
IGenericRepository:
public interface IRepository<T>
{
///<summary>
///Gets all entities
///</summary>
///<returns>All entities</returns>
IEnumerable<T> GetAll();
///<summary>
///Gets all entities matching the predicate
///</summary>
///<param name="predicate">The filter clause</param>
///<returns>All entities matching the predicate</returns>
IEnumerable<T> GetAll(Expression<Func<T, bool>> predicate);
///<summary>
///Set based on where condition
///</summary>
///<param name="predicate">The predicate</param>
///<returns>The records matching the given condition</returns>
IQueryable<T> Where(Expression<Func<T, bool>> predicate);
///<summary>
///Finds an entity matching the predicate
///</summary>
///<param name="predicate">The filter clause</param>
///<returns>An entity matching the predicate</returns>
IEnumerable<T> Find(Expression<Func<T, bool>> predicate);
///<summary>
///Determines if there are any entities matching the predicate
///</summary>
///<param name="predicate">The filter clause</param>
///<returns>True if a match was found</returns>
bool Any(Expression<Func<T, bool>> predicate);
///<summary>
///Returns the first entity that matches the predicate
///</summary>
///<param name="predicate">The filter clause</param>
///<returns>An entity matching the predicate</returns>
T First(Expression<Func<T, bool>> predicate);
///<summary>
///Returns the first entity that matches the predicate else null
///</summary>
///<param name="predicate">The filter clause</param>
///<returns>An entity matching the predicate else null</returns>
T FirstOrDefault(Expression<Func<T, bool>> predicate);
///<summary>
///Adds a given entity to the context
///</summary>
///<param name="entity">The entity to add to the context</param>
void Add(T entity);
///<summary>
///Deletes a given entity from the context
///</summary>
///<param name="entity">The entity to delete</param>
void Delete(T entity);
///<summary>
///Attaches a given entity to the context
///</summary>
///<param name="entity">The entity to attach</param>
void Attach(T entity);
}
Generic Repository:
public class GenericRepository<T> : IRepository<T> where T : class
{
///<summary>
///The database context for the repository
///</summary>
private DbContext _context;
///<summary>
///The data set of the repository
///</summary>
private IDbSet<T> _dbSet;
///<summary>
///Initializes a new instance of the <see cref="GenericRepository{T}" /> class.
///</summary>
///<param name="context">The context for the repository</param>
public GenericRepository(DbContext context)
{
this._context = context;
this._dbSet = this._context.Set<T>();
}
///<summary>
///Gets all entities
///</summary>
///<returns>All entities</returns>
public IEnumerable<T> GetAll()
{
return this._dbSet;
}
///<summary>
///Gets all entities matching the predicate
///</summary>
///<param name="predicate">The filter clause</param>
///<returns>All entities matching the predicate</returns>
public IEnumerable<T> GetAll(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
{
return this._dbSet.Where(predicate);
}
///<summary>
///Set based on where condition
///</summary>
///<param name="predicate">The predicate</param>
///<returns>The records matching the given condition</returns>
public IQueryable<T> Where(Expression<Func<T, bool>> predicate)
{
return this._dbSet.Where(predicate);
}
///<summary>
///Finds an entity matching the predicate
///</summary>
///<param name="predicate">The filter clause</param>
///<returns>An entity matching the predicate</returns>
public IEnumerable<T> Find(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
{
return this._dbSet.Where(predicate);
}
///<summary>
///Determines if there are any entities matching the predicate
///</summary>
///<param name="predicate">The filter clause</param>
///<returns>True if a match was found</returns>
public bool Any(Expression<Func<T, bool>> predicate)
{
return this._dbSet.Any(predicate);
}
///<summary>
///Returns the first entity that matches the predicate
///</summary>
///<param name="predicate">The filter clause</param>
///<returns>An entity matching the predicate</returns>
public T First(Expression<Func<T, bool>> predicate)
{
return this._dbSet.First(predicate);
}
///<summary>
///Returns the first entity that matches the predicate else null
///</summary>
///<param name="predicate">The filter clause</param>
///<returns>An entity matching the predicate else null</returns>
public T FirstOrDefault(Expression<Func<T, bool>> predicate)
{
return this._dbSet.FirstOrDefault(predicate);
}
///<summary>
///Adds a given entity to the context
///</summary>
///<param name="entity">The entity to add to the context</param>
public void Add(T entity)
{
this._dbSet.Add(entity);
}
///<summary>
///Deletes a given entity from the context
///</summary>
///<param name="entity">The entity to delete</param>
public void Delete(T entity)
{
this._dbSet.Remove(entity);
}
///<summary>
///Attaches a given entity to the context
///</summary>
///<param name="entity">The entity to attach</param>
public void Attach(T entity)
{
this._dbSet.Attach(entity);
}
}
Controller:
public class HomeController : Controller
{
///<summary>
///The context used for the controller
///</summary>
private DbContext _context;
///<summary>
///Initializes a new instance of the <see cref="HomeController"/> class.
///</summary>
public HomeController()
{
this._context = UnitOfWork.GetContext();
}
public JsonResult GetTopics()
{
var topics = new GenericRepository<Topic>(this._context).GetAll().ToList();
return this.Json(topics, JsonRequestBehavior.AllowGet);
}
///<summary>
///Disposes of the context if the currently disposing
///</summary>
///<param name="disposing">A value indicating whether or not the application is disposing</param>
protected override void Dispose(bool disposing)
{
if (disposing)
{
this._context.Dispose();
}
base.Dispose(disposing);
}
}
Im wesentlichen möchte ich sicherstellen, dass ich bin, Zugriff auf Daten in der richtigen Art und Weise und sicherstellen, dass ich nicht alles überblickt. Wieder, vielen Dank!
Sie möchten möglicherweise versuchen Sie es codereview.stackexchange.com. Dies ist nicht wirklich eine Frage für SO.
Diese Frage scheint off-topic, denn es ist mehr fit für CodeReview
Diese Frage scheint off-topic, denn es ist mehr fit für CodeReview
InformationsquelleAutor Duffp | 2013-10-31
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es ist nicht perfekt, um UnitOfWork implementieren als eine statische Klasse.
Definieren Sie eine Schnittstelle IUnitOfWork. Ihre db-Kontext wird diese Schnittstelle implementieren.
Es kann wie folgt Aussehen:
Ich in der Regel erstellen Sie mehrere repositories geerbt von generischen repository. Also Namen von repository-Methoden könnten mehr spezifische Namen. Auch dies verhindert die Duplizierung von repository-Logik in verschiedenen Steuerungen.
Beispiel:
Nun über controller: Zur Vereinfachung der Prüfung, es ist besser IoC-Container, z.B. NInject
So sind die Abhängigkeiten zwischen controller <-> repo <-> unitOfWork gelöst werden, indem NInject.
Wie diese Aussehen könnte UserController mit Login-Methode:
Die Abhängigkeiten auflösen könnte getan werden, indem benutzerdefinierte controller-factory, wie folgt:
Und ersetzen Sie den aktuellen controller factory mit Ihrem Brauch. Sie können es in der Application_Start-handler von Globalen.asax:
Wenn Sie sich entscheiden, NInject, können Sie einfach fügen Sie es mit Nuget. Zum aktivieren der Bindung InRequestScope Sie müssen auch NInject.Web.Common. Natürlich gibt es viele andere alternativen, wie Schloss Windsor oder StructureMap, aber NInject ist die einfachste.
Hoffe, es wird helfen.
IUnitOfWork
- Schnittstelle in diesem Beispiel (im Gegensatz zum übergeben eines einfachenEFDbContext
)? Ich habe gesehen (und verwendet) werden diese Muster, wenn dieIUnitOfWork
- Schnittstelle bietet abstrahiert Abfragen bzw. ändern-tracking-Methoden (um zu vermeiden, dass die Kupplung mit EF-Klassen direkt), aber die Weise, die Sie implementieren, müssen Sie Zugang zu einemIUnitOfWork
und einEFDbContext
Instanz -- haben Sie noch immer eine enge Bindung, aber jetzt müssen Sie auch mit einer zusätzlichen Schnittstelle, die bietet keine Funktionalität, die Sie nicht bereits durch IhreEFDbContext
.Wie du gesagt hast, es können vermeiden Kopplung zwischen EF und repositories. In meinem Fall habe ich zwei Arten von repos für EF und Azure Table Storage. Das ist, warum ich wirklich brauchen diese Entkopplung. Im aktuellen Fall hast du Recht, wir tun können, ohne IUnitOfWork. Ohnehin weniger Kupplung im gemeinsamen Szenario besser.
InformationsquelleAutor tabalin