Я довольно новичок в EF и DBContext, и поэтому ищу несколько советов о том, как лучше изложить мой код для службы WCF с использованием EF, Stored Procs или SQL.
Фон
У меня есть внешний интерфейс MVC3, который подключен к сервисному уровню WCF для доступа к данным (Oracle). Фактический доступ к данным осуществляется через отдельную библиотеку классов DAO.
Моя цель состоит в том, чтобы уровень обслуживания использовал только интерфейс, на котором он может вызывать набор методов для возврата данных. Я не хочу, чтобы сервисный уровень знал, что мы используем EF для запросов, поскольку я могу при необходимости заменить медленные биты EF на Stored Procs или обычный текст SQL.
Где я сейчас нахожусь
У меня есть интерфейс для моей базы данных IDB и конкретная реализация IDB, MyDB, которая также реализует DBContext. MyDb имеет пару производных классов, называемых MyStdDB и MySecureDB. Когда мне нужен интерфейс, я вызываю мой фабричный метод, который работает, если мне нужен стандартный или безопасный db, а затем возвращает его в мою переменную интерфейса.
Код WCF:
public List<string> GetAccount() {
IDB _db = DBFactory.GetInstance();
return _db.GetAccount();
}
DBФабричный код:
pubilc class DBFactory {
pubilc static IDB GetInstance()
{
if bSecure
return MySecureDB;
else
return MyStdDB;
}
}
Поэтому, когда я хочу запросить запрос, я хочу задать _db.GetAccount () в рамках моего вызова службы. На данный момент я добавил это как метод расширения интерфейса IDB. Причина этого состояла в том, чтобы служба не видела мои сущности EF, и это позволяет разбивать запросы на логические файлы, например. Класс, полный запросов CUSTOMER, класс, полный запросов ACCOUNT.
Код IDB:
public interface IDB : IDisposable
{
ObjectContext UnderlyingContext { get; }
int SaveChanges();
}
Код MyDB:
public class MyDB : DbContext, IDB
{
ObjectContext IDB.UnderlyingContext
{
get
{
return ((IObjectContextAdapter)this).ObjectContext;
}
}
int IDB.SaveChanges()
{
return SaveChanges();
}
public DbSet<Customer> Customer { get; set; }
}
Метод расширения:
public static List<string> GetAccount(this IDB _db)
{
((MyDB)_db).Customer.AsNoTracking().First();
}
Выпуск
Как видите, мне нужно привести интерфейс в конкретный объект, чтобы я мог добраться до сущностей EF. Это потому, что сущности находятся на реализации класса, а не интерфейса. Метод Extension находится в моей библиотеке классов DAO, поэтому он изменился бы, когда изменилась моя реализация IDB, но мне все равно это не нравится.
Есть ли лучший способ сделать это? Я смотрю на DI?
Большие драйверы для меня:
- Доступ к базе данных должен осуществляться только через интерфейс, так как мы можем заменить БД в ближайшее время.
- Методы доступа к данным должны быть скрыты от службы. Я должен иметь доступ к данным только через методы, предоставляемые интерфейсом / методами расширения и т. Д.