无法将实体框架成员更改为受保护

时间:2016-12-20 13:31:20

标签: c# .net asp.net-mvc entity-framework

我的应用程序中有以下DbContext类可以正常工作:

public partial class BaseContext : DbContext
{
    public virtual DbSet<Customer> Customers { get; set; }
    public virtual DbSet<Contact> Contacts { get; set; }
}

public partial class MyAppContext : BaseContext
{
    public new IQueryable<Customer> Customers()
    {
        return base.Customers.Where(n => n.Active == true);
    }

    public new IQueryable<Contact> Contacts()
    {
        return base.Contacts.Where(n => n.Active == true);
    }
}

我希望在我的应用程序中对客户或联系人的所有调用都可以过滤掉非活动记录。这种方法运作良好,但有人可能会在我的基本上下文中意外地调用客户或联系人,我想避免这种情况。

我认为理想的解决方案是使我的基本上下文中的成员受到保护,以便只能通过MyAppContext访问它们,但是这会失败,因为2 DbSet中没有加载任何数据。例如

public partial class BaseContext : DbContext
{
    protected virtual DbSet<Customer> Customers { get; set; }
    protected virtual DbSet<Contact> Contacts { get; set; }
}

当我将这些设置为受保护时,则不会加载任何数据,当它们是公共的时,每个都很好(但这会公开地暴露这些我想避免的)。

有没有人对如何解决这个问题有任何建议?

3 个答案:

答案 0 :(得分:2)

解决方案可能是不在基类上使用DbSet<>属性,而是使用流畅的API来声明您的实体类型:

public partial class BaseContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Customer>();
        modelBuilder.Entity<Contact>();
    }
}

然后在MyAppContext中,您可以这样声明您的属性:

public IQueryable<Customer> Customers =>
    Set<Customer>.Where(n => n.Active == true);
public IQueryable<Contact> Contacts =>
    Set<Contact>.Where(n => n.Active == true);

答案 1 :(得分:1)

您可以为他们提供实施,而不是将其设为自动属性。

public partial class BaseContext : DbContext
{
    protected virtual DbSet<Customer> Customers { get { return this.Set<Customer>(); } }
    protected virtual DbSet<Contact> Contacts { get { return this.Set<Contact>(); } }
}

答案 2 :(得分:0)

您可以使用空DbContext,然后将其实例传递到通用存储库,如下所示:

public class GenericRepository<T> : IGenericRepository where T : class, new()
{
    private readonly DbContext _context;
    private readonly DbSet<T> _set;

    public GenericRepository(DbContext context)
    {
        _context = _db;
        _set = _context.Set<T>();
    }

    public IQueryable<T> Query => _set.Where(m=>m.Active == true);

    public virtual void Add(T entity) => _set.Add(entity);

    public virtual void Update(T entity) => this._context.Entry(entity).State = EntityState.Modified;

    public virtual void Delete(T entity) =>  _set.Remove(entity);
}

此模式允许您对实体操作进行更精细的分级控制。您还可以使用不同的查询/更新逻辑实现不同的存储库。