Ответ 1
Ваш вопрос довольно широк. Например, что вы подразумеваете под "лучшим способом доступа к содержимому базы данных с помощью EF"? Лучший способ с точки зрения производительности?
Я попытаюсь ответить, предоставив вариант, который я предпочитаю (из которого я в основном использую какой-то вариант), который использует шаблон репозитория. Если вы будете использовать свои EF-наборы непосредственно в качестве репозитория, вы можете утверждать, что вам не нужен шаблон репозитория, но мне нравится обернуть их в один из моих собственных.
Так как я не могу понять, что вы имеете в виду наилучшим образом, я дам свои личные предпочтения, которые будут соответствовать типичному веб-проекту.
Я не буду публиковать весь код, чтобы он был полностью функциональным, но вы должны получить четкое представление о том, что происходит.
Настройка (4 проекта):
UI ---------- > Domain.Logic(w. Domain.Models) ----------------- > Данные (сохранение контекста EF).
Данные:
public partial class EFContextContainer : DbContext
enter code here
public EFContextContainer ()
: base("name=EFContextContainer")
{
}
public DbSet<IdentityUser> IdentityUsers { get;set; }
С оболочкой, возвращающей контекст:
public static class Database
{
public static EFContextContainerGetContext()
{
return new EFContextContainer();
}
}
У вас может быть такая настройка репозитория:
Интерфейс:
public interface IRepository<T> where T : class
{
IQueryable<T> GetAll();
T GetById(Guid id);
void Add(T entity);
void Update(T entity);
void Delete(T entity);
void Delete(Guid id);
}
Реализация (для краткости реализована только функция добавления (T)):
public class EFRepository<T> : IRepository<T>, IDisposable where T : class
{
public EFRepository(DbContext dbContext)
{
if (dbContext == null)
throw new ArgumentNullException("dbContext");
DbContext = dbContext;
DbSet = DbContext.Set<T>();
}
protected DbContext DbContext { get; set; }
protected DbSet<T> DbSet { get; set; }
public virtual void Add(T entity)
{
DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
if (dbEntityEntry.State != EntityState.Detached)
{
dbEntityEntry.State = EntityState.Added;
}
else
{
DbSet.Add(entity);
}
}
public void Dispose()
{
DbContext.Dispose();
}
}
Домен:
Domain.Logic(IdentityUserManager будет классом в Domain.Models):
public class IdentityUserManager
{
public void Add(IdentityUser idUser)
{
using(var idUserRepository = new EFRepository<IdentityUser>(Database.GetContext())
{
idUserRepository.Add(idUser);
}
}
}
интерфейс:
[HttpPost]
public ActionResult Post(UserViewModel model)
{
UserIdentity user = MapUser(model);
var userManager = new IdentityUserManager();
userManager.Add(user);
return View(new UserViewModel());
}
(Это не все, что написано в Visual Studio, поэтому пропустите любые орфографические ошибки.)
Признавая, в этом коде может быть намного больше абстракции, но было бы смешно записывать здесь полное решение. Например, вы можете использовать шаблон Unit of Work, который отлично работает с шаблоном репозитория. Поэтому прочитайте этот пример, а не полный справочник о том, как реализовать эту настройку. Вещи могут быть установлены намного чище, чем этот пример.
Для углубленного представления о реализации некоторых из этих шаблонов я настоятельно рекомендую вам взглянуть на курс отдельных приложений для страниц от John Papa on Plural Достопримечательность. Он отлично справляется с объяснением преимуществ этих моделей и способов их реализации.