0

I'm always having the problem on how to properly design having static entity instances and it being attached to Entity Framework's Dbcontext. For example, we have the following:

using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using Xunit;

namespace ClassLibrary1
{
    public class PersonType
    {
        public static readonly PersonType Student = new PersonType(1, "Student");
        public static readonly PersonType Teacher = new PersonType(2, "Teacher");
        public PersonType(int personTypeId, string description)
        {
            PersonTypeId = personTypeId;
            Description = description;
        }
        public int PersonTypeId { get; set; }
        public string Description { get; set; }
    }
    public class MyContext : DbContext
    {
        public DbSet<PersonType> PersonTypes { get; set; }
        public MyContext(DbContextOptions<MyContext> options) : base(options) { }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<PersonType>(builder =>
            {
                builder.HasData(
                    PersonType.Student,
                    PersonType.Teacher);
            });
        }
    }
    public class Tests
    {
        [Fact]
        public void This_test_fails()
        {
            var options = new DbContextOptionsBuilder<MyContext>()
                .UseInMemoryDatabase(Guid.NewGuid().ToString())
                .Options;

            using (var ctx = new MyContext(options))
                ctx.Database.EnsureCreated();

            using (var ctx = new MyContext(options))
            {
                //call Attach to pass
                //ctx.Attach(PersonType.Student);

                Assert.Equal(
                    PersonType.Student,
                    ctx.PersonTypes.First(p => p.Description == "Student"));
            }
        }
    }
}

The reason I need the static entity classes is for functions with logic based on PersonType (e.g. if(personType == PersonType.Student). To make this work, I need to call DbContext.Attach (which is easy to forget to call) so the context's PersonType will be equal to its corresponding static instance.

Is calling Attach the only way to solve this? Or is there something wrong with my design choices?

I'm primarily using EF Core but I believe this scenario is also present to EF6.

There is this open feature request issue in EF Core which would solve this problem but it seems not many people encounter this scenario so I'm thinking there's a different way to design this.

EDIT: There is a PersonTypes table in the database which is related to other tables.

1

The current implementation requires that you recompile the application if you later want to add teaching assistants. So that you might as well use Enums if you do not want to store the person types in the database.

Personally I would create a person type table in the database.

Secondly I would revisit the decision that you actually need to know, outside of the person class that is, which person type a person is. You should tell an instance of a class to do an action, not check what person type a person is and then decide what to do with the person.

  • PersonType is a table in the database. Edited my post to be clear on that. – Paolo Go Feb 8 at 17:12
  • I see. so instead of having a PersonType class. I would have a Person base class and then derived classes such as Student and Teacher that would have different implementations. Makes sense. – Paolo Go Feb 8 at 17:13
  • Sometimes, it doesn't work though. What if a Person is both a Student and Teacher. With having a PersonType, I could easily create a property Person.PersonTypes. Also, if a Person have other properties like Gender and MaritalStatus. – Paolo Go Feb 8 at 17:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.