Muszę ujawnić kontekst danych Entity Framework wtyczkom innych firm. Celem jest zezwolenie tym wtyczkom na pobieranie tylko danych, a nie pozwolenie im na wstawianie, aktualizowanie lub usuwanie lub jakiekolwiek inne polecenia modyfikacji bazy danych. Dlatego jak mogę uczynić kontekst danych lub jednostkę tylko do odczytu.
112
DbContext
, daj im jednąIQueryable
lub kilka.Odpowiedzi:
Oprócz łączenia się z użytkownikiem tylko do odczytu, istnieje kilka innych rzeczy, które możesz zrobić z DbContext.
źródło
AsNoTracking()
uniemożliwi korzystanie z leniwego ładowania.public override Task<int> SaveChangesAsync()
.(context as IObjectContextAdapter).ObjectContext.SaveChanges()
nadal będzie działać. Najlepszym wyborem jest użycieDbContext(string nameOrConnectionString);
konstruktora z ciągiem połączenia do odczytu / zapisu do tworzenia bazy danych, a następnie ciągiem połączenia tylko do odczytu.W przeciwieństwie do przyjętej odpowiedzi, uważam, że lepiej byłoby przedkładać kompozycję nad dziedziczenie . Wtedy nie byłoby potrzeby utrzymywania metod, takich jak SaveChanges, aby zgłosić wyjątek. Poza tym, po co w ogóle trzeba mieć takie metody? Należy zaprojektować klasę w taki sposób, aby jej konsument nie dał się zwieść, gdy spojrzy na listę metod. Interfejs publiczny powinien być zgodny z rzeczywistym zamiarem i celem klasy, podczas gdy w zaakceptowanej odpowiedzi posiadanie SaveChanges nie oznacza, że Context jest tylko do odczytu.
W miejscach, w których muszę mieć kontekst tylko do odczytu, na przykład po stronie odczytu wzorca CQRS , używam następującej implementacji. Nie zapewnia niczego poza możliwościami zapytań dla swojego konsumenta.
Korzystając z ReadOnlyDataContext, można mieć dostęp tylko do możliwości wykonywania zapytań dotyczących DbContext. Załóżmy, że masz jednostkę o nazwie Order, a następnie użyjesz instancji ReadOnlyDataContext w sposób jak poniżej.
źródło
IDisposable
public IQueryable<TEntity> Get<TEntity>() where TEntity : class { return _dbContext.Query<TEntity>().AsNoTracking(); }