Reputation: 15787
I am trying to follow the advice here: https://ardalis.com/encapsulated-collections-in-entity-framework-core
I have a class, which looks like this:
public class Person
{
public Guid Id { get; private set; }
public string Name { get; private set; }
private readonly List<PersonSport> _entries = new List<PersonSport>();
public IEnumerable<PersonSport> Entries => _entries.AsReadOnly();
public void AddEntry(PersonSport entry)
{
_entries.Add(entry);
}
}
and a dbcontext, which looks like this:
public class PersonSportContext : DbContext
{
public DbSet<Person> Person { get; set; }
public DbSet<Sport> Sport{ get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<PersonSport>().HasKey(sc => new { sc.PersonId, sc.SportId });
modelBuilder.Entity<Sport>()
.ToTable("Sport")
.HasDiscriminator<string>("SportType")
.HasValue<Football>("Football")
.HasValue<Running>("Running");
modelBuilder.Entity<PersonSport>()
.HasOne<Person>(sc => sc.Person)
.WithMany(s => s.PersonSport)
.HasForeignKey(sc => sc.PersonId);
modelBuilder.Entity<PersonSport>()
.HasOne<Sport>(sc => sc.Sport)
.WithMany(s => s.PersonSport)
.HasForeignKey(sc => sc.SportId);
var navigation = modelBuilder.Entity<Person>().Metadata.FindNavigation(nameof(ConsoleApp1.Person.PersonSport));
navigation.SetPropertyAccessMode(PropertyAccessMode.Field);
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=PersonSport;Trusted_Connection=True;MultipleActiveResultSets=true");
}
I see a compilation error:
"DbSet does not contain a definition for Entries".
I have highlighted the line that errors using a comment ('Entries' is underlined in red due to the compilation error). I have spent hours Googling this and have got nowhere. What am I doing wrong please?
Update cwharris's answer has helped with the compilation error. It now runs. I have created a Console app to test it:
static void Main(string[] args)
{
PersonSportContext personSportContext = new PersonSportContext();
var person = personSportContext.Person.Include(t => t.PersonSport).FirstOrDefault();
var sport = personSportContext.Sport.Include(t => t.PersonSport).FirstOrDefault();
Console.WriteLine("Finished");
}
Please see the screenshot below:
Notice that Person.PersonSport.Sport is null. Now see the below (when I stop the debugger on the following line):
Notice that Person.PersonSport.Sport is not null anymore.
Why is this? How can I ensure that Person.PersonSport.Sport is opulated when I populate the Person variable?
Upvotes: 1
Views: 610
Reputation: 18125
It looks like nameof(Person.Entries)
is intended to reference the Person
class, but is in fact looking at the Person
property of the PersonSportContext
class, due to a lack of name-spacing. Try prepending the Person
class namespace within the nameof
operator.
nameof(Person.Entries)
should become
nameof(MyNamespaceWherePersonClassResides.Person.Entries)
Upvotes: 4