Мне нужно открыть Контекст данных Entity Framework для сторонних плагинов. Цель состоит в том, чтобы позволить этим плагинам извлекать данные только и не позволять им выдавать вставки, обновления или удаления или любые другие команды изменения базы данных. Следовательно, как я могу сделать контекст данных или объект readonly.
Как сделать Entity Framework Data Context Readonly
Ответ 1
В дополнение к соединению с пользователем, доступным только для чтения, есть несколько других вещей, которые вы можете сделать для своего DbContext.
public class MyReadOnlyContext : DbContext
{
// Use ReadOnlyConnectionString from App/Web.config
public MyContext()
: base("Name=ReadOnlyConnectionString")
{
}
// Don't expose Add(), Remove(), etc.
public DbQuery<Customer> Customers
{
get
{
// Don't track changes to query results
return Set<Customer>().AsNoTracking();
}
}
public override int SaveChanges()
{
// Throw if they try to call this
throw new InvalidOperationException("This context is read-only.");
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Need this since there is no DbSet<Customer> property
modelBuilder.Entity<Customer>();
}
}
Ответ 2
В отличие от принятого ответа, я считаю, что было бы лучше отдать предпочтение композиции, а не наследованию. Тогда не было бы необходимости хранить такие методы, как SaveChanges, чтобы генерировать исключение. Более того, зачем вам такие методы вообще? Вы должны спроектировать класс таким образом, чтобы его потребитель не обманывался, когда просматривал список методов. Открытый интерфейс должен соответствовать фактическим намерениям и целям класса, в то время как в принятом ответе наличие SaveChanges не означает, что Context доступен только для чтения.
В местах, где мне нужен контекст только для чтения, например, на стороне чтения шаблона CQRS, я использую следующую реализацию. Он не предоставляет ничего, кроме запросов возможностей для своего потребителя.
public class ReadOnlyDataContext
{
private readonly DbContext _dbContext;
public ReadOnlyDataContext(DbContext dbContext)
{
_dbContext = dbContext;
}
public IQueryable<TEntity> Set<TEntity>() where TEntity : class
{
return _dbContext.Set<TEntity>().AsNoTracking();
}
public void Dispose()
{
_dbContext.Dispose();
}
}
Используя ReadOnlyDataContext, вы можете получить доступ только к возможностям запросов DbContext. Допустим, у вас есть сущность с именем Order, тогда вы будете использовать экземпляр ReadOnlyDataContext так, как показано ниже.
readOnlyDataContext.Set<Order>().Where(q=> q.Status==OrderStatus.Delivered).ToArray();