简体   繁体   中英

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 . I have the following requirements:

  1. Save all the custom classes into one table, the Device table.
  2. Each custom class may contain different properties depending on the functionality of the class (device).
  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. 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 .

I am currently using Discriminator and it works, but it only runs once, and thus does not support adding custom classes at runtime. How can I solve this issue?

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:

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). 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.

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