简体   繁体   中英

EF Core seeding data in Sqlite and WPF with relational model - unable to create an object of type DbContext error

I'm creating a WPF app in .NET 6 with Entity Framework Core and Sqlite.

I have the following relational model (note some nullable fields are omitted for the sake of brevity):

[Table("Contacts")]
public class Contact
{
    public Guid Id { get; set; }
    [Required]
    public string Title { get; set; }
    [Required]
    public string FirstName { get; set; }
    [Required]
    public string LastName { get; set; }
    public ContactGroup? Parent { get; set; }
    public Guid? ParentId { get; set; }
}

[Table("ContactGroups")]
public class ContactGroup
{
    public Guid Id { get; set; }
    [Required]
    public string Name { get; set; }
    public ContactGroup? Parent { get; set; }
    public Guid? ParentId { get; set; }
    public ObservableCollection<ContactGroup> SubGroups { get; set; } = new ObservableCollection<ContactGroup>();
    public ObservableCollection<Contact> Contacts { get; set; } = new ObservableCollection<Contact>();
}//class

That is, a ContactGroup can have zero or more Contact s.

I want to seed some data to the Sqlite database, with one of the contacts belonging to a contact group, and one contact without a parent, like so:

public class ContactsContext : DbContext
{
    public DbSet<Contact> Contacts => Set<Contact>();
    public DbSet<ContactGroup> ContactGroups => Set<ContactGroup>();

    public ContactsContext()
    {
        Database.EnsureDeleted();
        Database.EnsureCreated();
    }
        
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite("Data Source=contacts.db");
    }
        
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    { 
        modelBuilder.Entity<ContactGroup>(entity =>
        {
            entity.HasKey(x => x.Id);
            entity.Property(x => x.Name);
            entity.HasOne(x => x.Parent)
                .WithMany(x => x.SubGroups)
                .HasForeignKey(x => x.ParentId)
                .IsRequired(false)
                .OnDelete(DeleteBehavior.Cascade);
            entity.HasMany(x => x.Contacts);
        });

        Contact c1 = new Contact { Id = Guid.NewGuid(), Title = "Mr", FirstName = "John", LastName = "Smith" };
        Contact c2 = new Contact { Id = Guid.NewGuid(), Title = "Mrs", FirstName = "Jane", LastName = "Doe" };
        ContactGroup g1 = new ContactGroup { Id = Guid.NewGuid(), Name = "Social" };
        g1.Contacts.Add(c1);
        c1.Parent = g1;
        c1.ParentId = g1.Id;

        modelBuilder.Entity<ContactGroup>().HasData(
            g1
            );
        modelBuilder.Entity<Contact>().HasData(
            c1,
            c2
            );
    }
}//class

When trying to create a migration from this, I get the following error:

Unable to create an object of type 'ContactsContext'

What could be causing this and how to fix it?

Maybe it's not a good idea to call EnsureCreated and EnsureDeleted in the constructor. In my opinion that should be outside in some kind of Startup.cs file. Just move it outside... This way, it's probably causing your problem.

Database.EnsureDeleted() and Database.EnsureCreated() should not be called from inside the constructor but should be called in a method that should be run on start up.

This is the typical way of using the methods:

public static void SetupContactsContext()
{
    using (var context = new ContactsContext())
    {
        context.Database.EnsureDeleted();
        context.Database.EnsureCreated();
    }
}

The above method should be called on start-up.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM