Entity Framework Core: проблема при динамическом обновлении сущностей с помощью построителя моделей.C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Entity Framework Core: проблема при динамическом обновлении сущностей с помощью построителя моделей.

Сообщение Anonymous »

В настоящее время я пытаюсь разработать центральное приложение с надстройками. Центральное приложение хранит основные объекты (например, AppEntity, AppRole, Device, ...). У него есть собственный DBContext.
Я хотел бы добавить несколько объектов при импорте дополнений. Например, я хотел бы добавить объект (и связанную с ним таблицу в базе данных) во время импорта модуля.
В модуле я создал класс, реализующий IEntityTypeConfiguration : OK

Код: Выделить всё

public class BitLockerVolumeKeyProtectorConfiguration : IEntityTypeConfiguration
{
public void Configure(EntityTypeBuilder builder)
{
builder.HasNoKey();
builder.Property( t => t.KeyProtectorId ).IsRequired();
builder.Property(t => t.MountPoint).IsRequired();
builder.Property(t => t.RecoveryPassword).IsRequired();
builder.Property(t => t.CreationDate).IsRequired();
builder.HasOne("Device");

builder.ToTable("BitLockerVolumeKeyProtectors");
}
}
В приложении я создал дополнительную службу, которая отвечает за загрузку Dll: ОК

Код: Выделить всё

public class AddOnService : IAddOnService
{
private readonly ILogger _logger;
private readonly List _addons = new List();

public AddOnService(ILogger logger)
{
_logger = logger;
}

public async Task LoadAddonsAsync()
{
_logger.LogInformation($"Start Loading Addons");

_addons.Clear();
var test = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var addonAssemblies = Directory.GetFiles($"{test}\\Addons", "*.dll");

if (addonAssemblies.Count() > 0)
{
foreach (var assemblyPath in addonAssemblies)
{
_logger.LogInformation($"Start Loading Addon [{assemblyPath}]");

var assembly = Assembly.LoadFrom(assemblyPath);
var addonTypes = assembly.GetTypes().Where(t => typeof(IAddOn).IsAssignableFrom(t) && !t.IsInterface);

if (addonTypes.Count() > 0)
{
foreach (var type in addonTypes)
{
var addon = Activator.CreateInstance(type) as IAddOn;

if (addon != null)
{
_addons.Add(addon);
}
}
}
}
}
else
{
_logger.LogInformation($"No Addon to load");
}

await Task.CompletedTask;
}

public async Task RegisterEntitiesAsync(ModelBuilder modelBuilder)
{
foreach (var addon in _addons)
{
await addon.RegisterEntitiesAsync(modelBuilder);
}
}

public async Task SeedDataAsync(IServiceProvider serviceProvider)
{
foreach (var addon in _addons)
{
_logger.LogInformation($"Start Seeding data for Addon [{addon.Name}]");
await addon.SeedDataAsync(serviceProvider);
}
}
}
В приложении я создал DatabaseInitializer, который отвечает за обновление Dbcontext путем импорта любого класса, реализующего IEntityTypeConfiguration из любого загруженный аддон. Эта операция выполняется с помощью modelBuilder.ApplyConfigurationsFromAssembly().

Код: Выделить всё

public class DatabaseInitializer
{
private readonly IServiceProvider _serviceProvider;
private readonly IApplicationDBContext _dbContext;
private readonly IAddOnService _addOnService;

public DatabaseInitializer(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
_dbContext = serviceProvider.GetRequiredService();
_addOnService = serviceProvider.GetRequiredService();
}

public async Task Initialize()
{
await _dbContext.ReconfigureModelAsync();

await _addOnService.SeedDataAsync(_serviceProvider);
}
}

Код: Выделить всё

public class BitLockerManagement : IAddOn
{
public Guid Id => Guid.Parse("9d877d65-96bd-474d-ae20-45873f51a2f4");

public string Name => "BitLocker Management";

public IReadOnlyDictionary AddonRoles => Roles.List;

public async Task RegisterEntitiesAsync(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
await Task.CompletedTask;
}

public async Task SeedDataAsync(IServiceProvider serviceProvider)
{
var context = serviceProvider.GetService();
var roleManager = serviceProvider.GetService();

// Inject Module Roles
//using (var scope = serviceProvider.CreateScope())
//{
//    var context = scope.ServiceProvider.GetRequiredService();
//    var roleManager = scope.ServiceProvider.GetRequiredService();

// Inject Addons AppRoles
foreach(KeyValuePair role in AddonRoles)
{
if (!context.AppRoles.Any(r => r.Name == role.Key))
{
await roleManager.CreateAsync(AppRole.CreateInstance(role.Key, role.Value.Description));
}
}

// Test creating RecoveryPasswordRecord
var device = context.Devices.FirstOrDefault(d => d.SerialNumber == "5CG1263PK8");

if (device != null)
{
var recoveryPasswordInformation = BitLockerVolumeKeyProtector.CreateRecoveryPasswordInstance(device, "90595464-9272-472F-A8FD-3ECD070F5BAF", "431761-571725-276870-448547-187220-398805-243375-347688", "C:");

await (context as DbContext).AddAsync(recoveryPasswordInformation);

//await (context as DbContext).Set()
//    .AddAsync(recoveryPasswordInformation);

//var tpmPinInformation = BitLockerVolumeKeyProtector.CreateTPMPinInstance(device, "425E47A9-1A74-46B3-888D-54282D0BFC71", "0662007682", "C:");
//await (context as DbContext).Set()
//    .AddAsync(tpmPinInformation);
await (context as DbContext).SaveChangesAsync();
}
//}
}
}
В конце инициализации базы данных (особенно я вижу, что в свойство dbContext.Model добавлен новый объект.
Моя проблема возникает при вызове _dbcontext.ReconfigureModelAsync(). Этот метод определен в моем DBContext:

Код: Выделить всё

public class ApplicationDBContext : DbContext, IApplicationDBContext
{
private readonly IAddOnService _addonService;

public ApplicationDBContext(DbContextOptions options, IAddOnService addOnService)
: base(options)
{
_addonService = addOnService;
}

public DbSet AppRoles { get; set; }
public DbSet AppEntities { get; set; }
public DbSet Devices { get; set; }

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

modelBuilder.Entity()
.HasDiscriminator("Discriminator")
.HasValue("ClientApp")
.HasValue("ADUser")
.HasValue("ADGroup");

modelBuilder.Entity()
.HasIndex(u => u.LoginName)
.IsUnique();

modelBuilder.Entity()
.Property(p => p.Sid)
.HasColumnName("Sid");

modelBuilder.Entity()
.HasIndex(u => u.Sid)
.IsUnique();

modelBuilder.Entity()
.HasMany(e => e.Roles)
.WithMany(e => e.Users)
.UsingEntity("AppEntities_AppRoles");

await modelBuilder.ApplyAddonEntitiesAsync(_addonService);
}

public async Task ReconfigureModelAsync()
{
var modelBuilder = new ModelBuilder( new Microsoft.EntityFrameworkCore.Metadata.Conventions.ConventionSet() );

OnModelCreating(modelBuilder);

//await modelBuilder.ApplyAddonEntitiesAsync(_addonService);
}

public override IModel Model => base.Model;
}
В конце OnModelCreating(ModelBuilder modelBuilder) я вижу новый объект, добавленный в модель, но как только он выходит за пределы OnModelCreating, этот объект исчезает большая часть сущностей.
Есть идеи?
Заранее спасибо

Подробнее здесь: https://stackoverflow.com/questions/785 ... -model-bui
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Entity Framework Core 8 — сопоставление двух сущностей с одной и той же таблицей с помощью разных фильтров (PostgreSQL)
    Anonymous » » в форуме C#
    0 Ответы
    11 Просмотры
    Последнее сообщение Anonymous
  • Привязка моделей Entity Framework Core к методу действия в контроллере ASP.NET Core
    Anonymous » » в форуме C#
    0 Ответы
    124 Просмотры
    Последнее сообщение Anonymous
  • Entity Framework Core 8: обновление дочерних сущностей
    Anonymous » » в форуме C#
    0 Ответы
    18 Просмотры
    Последнее сообщение Anonymous
  • Entity Framework Core 8: обновление дочерних сущностей
    Anonymous » » в форуме C#
    0 Ответы
    11 Просмотры
    Последнее сообщение Anonymous
  • Entity Framework Core 8. Ошибка случайной ссылки на объект FindAsync @ System.Data.Entity.Core.Common.Internal.Materiali
    Anonymous » » в форуме C#
    0 Ответы
    42 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C#»