在EF6 DbSet上拒绝读/写

时间:2018-01-07 16:57:45

标签: c# entity-framework entity-framework-6

我有一个我想要通过它的父实体管理的实体。考虑购买物品,供应商列表和批准供应商的物品:

// DOMAIN
public class Item {
    public string Name { get; set; }
    public virtual ICollection<ApprovedVendor> ApprovedVendors { get; set; }
}

public class Vendor {
    public string Name {get; set; }
}

public class ApprovedVendor {
    public int ItemID {get;set;}
    public int VendorID {get;set;}
    public decimal? Cost {get;set;}

    public virtual Item Item {get;set;}
    public virtual Vendor Vendor {get;set;}
}

// DATA (DbContext mappings)
public DbSet<ApprovedVendor> ApprovedVendors {get;set;}
public DbSet<Item> Items {get;set;}
public DbSet<Vendor> Vendors {get;set;}

// fluent entity mappings as per usual

我尝试做的是从外部程序集中删除对context.ApprovedVendors的访问权限,从而允许仅通过Item管理已批准的供应商。但是,我仍然需要适当的EF6映射。此外,对于集成测试以确保从连接的数据库构建模型,我必须从测试项目访问DbSet<ApprovedVendor>。因此,我做了以下更改:

// in PDB.Data AssemblyInfo.cs
[assembly: InternalsVisibleTo("PDB.Data.Tests.Integration")]

// in dbcontext
internal DbSet<ApprovedVendor> ApprovedVendors {get;set;}   

// in PDB.Data.Tests.Integration
[TestMethod]
public void BuildsApprovedVendor() {
    var sut = _context.ApprovedVendors.FirstOrDefault();
    if (sut == null) {
        Assert.Inconclusive();
    }
    Assert.IsInstanceOfType(sut, typeof(Domain.Items.ApprovedVendor));
}

我认为这样做,但似乎DbSet<ApprovedVendor> 必须是公开的,因为我在运行测试时遇到以下错误:

  

PDB.Data.Tests.Integration.ModelBuilding.BuildsApprovedVendor抛出异常:   System.ArgumentNullException:值不能为null。   参数名称:source

如果我将internal更改回public,一切正常(除非现在我的DbSet再次公开...)

我可以这样做(我是否遗漏了某些内容),或者我是否坚持在公共DbSet上抛出Obsolete属性并希望未来的开发者注意?

1 个答案:

答案 0 :(得分:1)

您可以像这样定义dbset:

public DbSet<ApprovedVendor> ApprovedVendors {internal get;set;}

这将阻止从其他程序集中执行任何操作(因为getter是内部的),除了设置它,这通常没有任何意义。同时,因为setter仍然是公开的--EF将能够正确地映射该组。