How to make Entity Framework Data Context Readonly

前端 未结 2 1602
别跟我提以往
别跟我提以往 2020-11-28 19:11

I need to expose an Entity Framework Data Context to 3rd party plugins. The purpose is to allow these plugins to fetch data only and not to let them issue inserts, updates o

相关标签:
2条回答
  • 2020-11-28 19:33

    As opposed to the accepted answer, I believe it would be better to favor composition over inheritance. Then there would be no need for keeping methods such as SaveChanges to throw an exception. Moreover, why do you need to have such methods in the first place? You should design a class in a way that its consumer doesn't get fooled when it looks at its list of methods. The public interface should be in align with the actual intent and goal of the class while in the accepted answer having SaveChanges doesn't imply that Context is read-only.

    In places where I need to have a read-only context such as in the Read side of CQRS pattern, I use the following implementation. It doesn't provide anything other than Querying capabilities to its consumer.

    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();
        }
    }
    

    By using ReadOnlyDataContext, you can have access to only querying capabilities of DbContext. Let's say you have an entity named Order, then you would use ReadOnlyDataContext instance in a way like below.

    readOnlyDataContext.Set<Order>().Where(q=> q.Status==OrderStatus.Delivered).ToArray();
    
    0 讨论(0)
  • 2020-11-28 19:37

    In addition to connecting with a read-only user, there are a few other things you can do to your 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>();
        }
    }
    
    0 讨论(0)
提交回复
热议问题