简体   繁体   English

使用运行时加载支持将派生类保存到 EF Core 中的单个表

[英]Saving derived classes to a single table in EF Core with runtime loading support

I have some custom classes, such as BarcodeDevice and LightDevice , which are derived from a base class called Device .我有一些自定义类,例如BarcodeDeviceLightDevice ,它们派生自名为Device的基类 class。 I have the following requirements:我有以下要求:

  1. Save all the custom classes into one table, the Device table.将所有自定义类保存到一个表中,即Device表。
  2. Each custom class may contain different properties depending on the functionality of the class (device).每个自定义 class 可能包含不同的属性,具体取决于 class(设备)的功能。
  3. Some custom classes are already loaded together with the project, while others will be created later on and loaded in some way, for example by uploading a Dll file.一些自定义类已经与项目一起加载,而其他自定义类将在稍后创建并以某种方式加载,例如通过上传Dll文件。 Therefore, once the project goes live, the code cannot be changed.因此,一旦项目上线,代码就无法更改。
  4. The individual custom classes can be retrieved by loading the Device object from the database using DbContext .可以通过使用DbContext从数据库加载Device object 来检索各个自定义类。

I am currently using Discriminator and it works, but it only runs once, and thus does not support adding custom classes at runtime.我目前正在使用Discriminator并且它可以工作,但它只运行一次,因此不支持在运行时添加自定义类。 How can I solve this issue?我该如何解决这个问题?

DbContext : DbContext

public class ApplicationDbContext : IdentityDbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    public DbSet<Device> Devices { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // Configure device type for each type.
        modelBuilder.Entity<BarcodeDevice>()
            .HasDiscriminator(p => p.Type)
            .HasValue(nameof(BarcodeDevice));
        
        modelBuilder.Entity<LightDevice>()
            .HasDiscriminator(p => p.Type)
            .HasValue(nameof(LightDevice));
    }
}

Custom Class:自定义 Class:

public class BarcodeDevice : Device
{
    [Required]
    public string Type { get; set; }
    
    private SerialPort serial { get; set; }
    private string barcodeValue { get; set;}
    
    // other properties
}

Service:服务:

public class DeviceService : IDeviceService
{
    // Some variables
    
    public DeviceService(IServiceScopeFactory serviceScopeFactory)
    {
        _serviceScopeFactory = serviceScopeFactory;
        var dbContext = _serviceScopeFactory.CreateScope()
            .ServiceProvider.GetRequiredService<ApplicationDbContext>();

        Devices = dbContext.Devices.ToList();

        for (int i = 0; i < Devices.Count; i++)
        {
            Devices[i].StartInstance();
            Devices[i].OnMessageSend += Device_OnMessageSend;
        }

        _mqttClient = _serviceScopeFactory.CreateScope()
            .ServiceProvider.GetRequiredService<IResolverMqttClient>();

        _mqttClient.OnMqttMessageReceived += MqttClient_OnMqttMessageReceived;
    }
    
    // some methods
}

Your options.你的选择。

  1. Push back on 3).推回 3)。 Do you really need that?真的需要吗?

  2. don't use EF,不要使用英孚,

or或者

  1. have only a JSON column mapped to store the varying attributes of each device type.只有一个 JSON 列映射到存储每个设备类型的不同属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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