Reputation: 7792
I have an entity that I want managed only through it's parent entity. Consider purchased Items, a list of Vendors, and Approved Vendors for an Item:
// 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
What I'm trying to do is remove access to the context.ApprovedVendors
from external assemblies, thus allowing approved vendors to only be managed through an Item
. However, I still need the EF6 mappings as appropriate. Additionally, for integration tests to ensure the model builds from the connected database, I must access the DbSet<ApprovedVendor>
from a test project. Thus, I made the following changes:
// 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));
}
I thought this would do, but it appears that the DbSet<ApprovedVendor>
must be public, as I get the following error running the test:
PDB.Data.Tests.Integration.ModelBuilding.BuildsApprovedVendor threw exception: System.ArgumentNullException: Value cannot be null. Parameter name: source
If I change internal
back to public
, everything works fine (except now my DbSet is public again...)
Can I do this (am I missing something), or am I stuck with throwing an Obsolete
attribute on a public DbSet and hoping future devs pay attention?
Upvotes: 1
Views: 150
Reputation: 101443
You can define dbset like this:
public DbSet<ApprovedVendor> ApprovedVendors {internal get;set;}
This will prevent doing anything with it from another assemblies (because getter is internal), except setting it, which usually doesn't make sense anyway. At the same time, because setter is still public - EF will be able to map that set correctly.
Upvotes: 2