实体框架7和SQLite的复合密钥

本文关键字:复合 密钥 SQLite 框架 实体 | 更新日期: 2023-09-27 18:21:32

提前感谢您的帮助!

因此,我正在开发一个WPF应用程序,并使用带有实体框架7.0.0-Beta8的SQLite作为我的ORM框架。我正在尝试创建一个复合密钥,以防止多次插入相同的数据。不幸的是,当我使用EF Fluent代码执行类似modelBuilder.Entity<DeviceConfiguration>().HasKey(d => new {d.property1, d.property2})的操作时,我会得到一个System.NotSupportedException

System.NotSupportedException未处理HResult=-214623067
消息=SQLite无法支持此迁移操作
Source=EntityFramework.Sqlite

导致此错误的代码在这里。

public class Device
{
   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   public Guid Id { get; set; }
   public string DeviceType { get; set; }
   public UInt32 DeviceIdentifier { get; set; }
   public string PreferredConnection { get; set; }
   public List<DeviceConfiguration> DeviceConfiguration { get; set; }
}
public class DeviceConfiguration
{
   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   public Guid Id { get; set; }
   public string DeviceType { get; set; }
   public UInt32 DeviceIdentifier { get; set; }
   public string Description { get; set; }
   public string DateTime { get; set; }
   public string Configuration { get; set; }
   public string Reason { get; set; }
   public List<Device> Device { get; set; }
}
public class DeviceContext : DbContext
{
   public DbSet<Device> Devices { get; set; } 
   public DbSet<DeviceConfiguration> DeviceConfigurations { get; set; } 
   public DbSet<PidTuningSet> PidTuningSets { get; set; }
   protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
   {
       string databaseFilePath =  "RUI.db";
       try
       {
           databaseFilePath = Path.Combine(
               Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), 
               databaseFilePath);
       }
       catch (InvalidOperationException) { }
       optionsBuilder.UseSqlite($"Data source={databaseFilePath}");
   }
   protected override void OnModelCreating(ModelBuilder modelBuilder)
   {
       modelBuilder.Entity<Device>()
           .Property(d => d.DeviceType)
           .IsRequired();
       modelBuilder.Entity<Device>()
           .Property(d => d.DeviceIdentifier)
           .IsRequired();
       modelBuilder
           .Entity<DeviceConfiguration>()
           .HasKey(d => new {d.DeviceIdentifier, d.DeviceType});
       modelBuilder.Entity<DeviceConfiguration>()
           .Property(d => d.Description)
           .IsRequired();
       modelBuilder.Entity<DeviceConfiguration>()
           .Property(d => d.DateTime)
           .IsRequired();
       modelBuilder.Entity<DeviceConfiguration>()
           .Property(d => d.Configuration)
           .IsRequired();
       modelBuilder.Entity<DeviceConfiguration>()
           .Property(d => d.Reason)
           .IsRequired();
       modelBuilder.Entity<PidTuningSet>()
           .Property(d => d.Locked)
           .IsRequired();
       modelBuilder.Entity<PidTuningSet>()
           .Property(d => d.PIDValues)
           .IsRequired();
       modelBuilder.Entity<PidTuningSet>()
           .Property(d => d.Description)
           .IsRequired()
           .HasMaxLength(32);
   }
}

如果我注释掉modelBuilder.Entity<DeviceConfiguration>().HasKey(d => new {d.DeviceIdentifier, d.DeviceType});代码并创建一个新的迁移,它就可以工作了。但如果我不注释它,创建一个新的迁移并运行它,我会得到上面不支持的异常。我不确定EF7是否支持此操作,或者是否有更好的方法来确保数据库中没有任何重复的数据。

实体框架7和SQLite的复合密钥

我在模型级别上创建了这个键,只需创建一个属性,使用[key]标记并连接值。我不喜欢这种方法,如果可能的话,我想通过EF来做到这一点。