W tym poście przedstawię swoją implementację wzorca Repository z użyciem Entity Framework. Na początek zdefiniowałem interfejs IRepository:
public interface IRepository where T : EntityObject { IQueryable All(); T SingleOrDefault(Expression<Func<T, bool>> predicate); void Add(T entity); void Delete(T entity); void Save(); }
Następnie kolej na implementację klasy Repository:
public class Repository : IRepository where T : EntityObject { #region private members private readonly ObjectContext context; #endregion #region constructors public Repository(ObjectContext context) { this.context = context; } #endregion #region public methods #region IRepository Members public IQueryable All() { return this.context.CreateQuery( this.context.MetadataWorkspace .GetEntitySetName(typeof(T).Name)); } public T SingleOrDefault(Expression<Func<T, bool>> predicate) { return this.All().Where(predicate).FirstOrDefault(); } public void Add(T entity) { this.context.AddObject(this.context.MetadataWorkspace .GetEntitySetName(typeof(T).Name), entity); } public void Delete(T entity) { this.context.DeleteObject(entity); } public void Save() { this.context.SaveChanges(); } #endregion #endregion }
Zdefiniowałem też Extension Method dla klasy MetadataWorkspace, żeby być w stanie pobrać tzw. Entity Set Name:
public static class MetadataWorkspaceExtensions { public static string GetEntitySetName(this MetadataWorkspace mdw, string entityName) { EntityContainer entityContainer = mdw.GetItems(DataSpace.CSpace).First(); EntitySetBase entitySet = entityContainer.BaseEntitySets.Where(e => e.ElementType.Name.Equals(entityName)) .FirstOrDefault(); return entitySet.Name; } }
Przykładowe użycie stworzonej klasy może wyglądać np. w ten sposób:
Hero hero = Hero.CreateHero(0, 0, 0, 0, "Test hero name", 0); DotBeerEntities entities = new DotBeerEntities(); IRepository heroRepository = new Repository(entities); heroRepository.Add(hero); heroRepository.Save();
W tym tygodniu udało mi się przenieść dane z plików XML do bazy danych SQLite. W nadchodzącym tygodniu postaram się zmienić logikę DotBeer’a tak żeby używała Entity Framework.
Entity Framework i wzorzec Repository « Damian Antonowicz…
Dziękujemy za publikację – Trackback z dotnetomaniak.pl…
T SingleOrDefault(Func predicate) – ta funkcja pobierze wszystkie dane, a później za pomocą linq to object znajdzie element.
W argumencie powinno być T SingleOrDefault(Expression<Func> predicate)
@Piotr N
Masz rację. Przykład poprawiony. Dzięki za zwrócenie uwagi 🙂
chyba przydała by się jeszcze metoda Update(T entity) w IRepository ;), ja zawsze dodaje chociaż używam NHibernate więc tu może być inaczej.
[…] DotBeer Wpisy Komentarze ← Entity Framework i wzorzec Repository […]
@Gdynia
Akurat taka metoda nie jest potrzebna. Wystarczy pobrać jakąś encję, poddać edycji i wykonać metodę Save. Np. tak:
IRepository heroRepository = new Repository(new DotBeerEntities());
Hero hero = heroRepository.SingleOrDefault(h => h.Name == “Abaddon, the Lord of Avernus”);
hero.Name = “Kelov Darkhum”;
heroRepository.Save();
Entity Framework rozpozna, które encje zostały zmienione i wykona odpowiednie polecenia SQL na bazie danych 🙂