Home > Net >  DbContext failed with InvalidOperationException when add new field ionto my binding object
DbContext failed with InvalidOperationException when add new field ionto my binding object

Time:03-26

So this is my binding type:

public class ClipboardItem : INotifyPropertyChanged
    {        
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        private int id { get; set; }
        private string text;
        private string name;        
        private string processName;
        private string time;

        public ClipboardItem(int id, string text, string name, string processName, string time, bool isPinned)
        {
            this.id = id;
            this.text = text;
            this.name = "";          
            this.processName = processName;
            this.time = time;
        }
}

DbContext

public class ClipboardItemContext : DbContext
    {
        public DbSet<ClipboardItem> Clipboards { get; set; }
        public string DbPath { get; }

        public ClipboardItemContext()
        {
            var folder = Environment.SpecialFolder.LocalApplicationData;
            var path = Environment.GetFolderPath(folder);
            DbPath = System.IO.Path.Join(path, "clipboards.db"); 
            Database.EnsureCreated();
        }

        // The following configures EF to create a Sqlite database file in the
        // special "local" folder for your platform.
        protected override void OnConfiguring(DbContextOptionsBuilder options) => options.UseSqlite($"Data Source={DbPath}");

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {

            modelBuilder.Entity<ClipboardItem>().HasKey(p => new { p.Id });
        }
    }

So this works fine and I can add, read, update and delete items from my DB.

Now I want to add new field into my binding type:

private bool isPinned;

My Ctor

public ClipboardItem(int id, string text, string name, string processName, string time, bool isPinned)
        {
            this.id = id;
            this.text = text;
            this.name = "";          
            this.processName = processName;
            this.time = time;
            this.isPinned= isPinned;
            Properties.Settings.Default.ItemIndex  ;
        }

Before run my application again I deleted my .db file because this new field and when try to start my application I got this exception:

System.InvalidOperationException: 'No suitable constructor was found for entity type 'ClipboardItem'. The following constructors had parameters that could not be bound to properties of the entity type: cannot bind 'isPinned' in 'ClipboardItem(int id, string text, string name, string processName, string time, bool isPinned)'.'

I seems that my DB not accept this new field, I also try to add different type for example int or string but again I got the same error.

When I removed this new field my .db created and my application running.

CodePudding user response:

Sqlite does not have a separate Boolean storage class. Instead, Boolean values are stored as integers 0 (false) and 1 (true)

Just map your field to integer,

[Column(TypeName = "INTEGER")]
public bool isPinned;

Or you can use OnModelCreating to do it,

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
     modelBuilder.Entity<ClipboardItem>().HasKey(p => new { p.Id });
     modelBuilder.Entity<ClipboardItem>().Property(p => p.isPinned)    
                                            .HasConversion(x => x ? 1 : 0,       
                                                           x => (x == 1));
}
  • Related