如何动态地将DbSet注册到DbContext中并向表中添加一行?

问题描述 投票:0回答:1

我有太多实体,注册每个实体都让我头疼,更不用说实例化 dbcontext 的负载了。 所以我尝试动态注册数据库集。

为了将 DbSet 动态注册到 DbContext 中,我使用了此链接中的文章: 文字 我添加了扩展名作为文件:

public static class ModelBuilderExtensions
{
    public static void RegisterAllEntities<BaseModel>(this ModelBuilder modelBuilder, params Assembly[] assemblies)
    {
        IEnumerable<Type> types = assemblies.SelectMany(a => a.GetExportedTypes()).Where(c => c.IsClass && !c.IsAbstract && c.IsPublic &&
          typeof(BaseModel).IsAssignableFrom(c));
        foreach (Type type in types)
            modelBuilder.Entity(type);
    }
}

然后我创建了一个名为 BaseEntity 的抽象类,我的所有实体都实现了它。

在 ApplicationDbContext 内部我重写了 OnModelCreating 方法:

protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            var entitiesAssemblyInt = typeof(BaseEntity<int>).Assembly;
            var entitiesAssemblyGuid = typeof(BaseEntity<Guid>).Assembly;
            modelBuilder.RegisterAllEntities<BaseEntity<int>>(entitiesAssemblyInt);
            modelBuilder.RegisterAllEntities<BaseEntity<Guid>>(entitiesAssemblyGuid);
        }

它在迁移中完美运行,但是当我想在 commandHandler 中使用 dbcontext 将一行添加到名为 client 的表中时,我不知道如何从上下文调用 client。

context.Client.Add(客户端);

不起作用,因为我没有将 dbset 直接注册到 dbcontext 中,并且上下文中没有客户端。

c# .net reflection entity-framework-core ef-model-builder
1个回答
0
投票

在我看来,这通常是一个坏主意*,出于可维护性、调试、可读性的原因......这样的例子不胜枚举。

但是,如果必须,您可以使用

_context.Set<Donation>()
来获取给定实体的 DbSet。

示例

以下代码具有正确注册的 DbSet 和上下文。

这是 推荐方式

    public async Task<Donation?> GetDonationAsync(Guid donationID)
    {
        return await _context.Donations
            .Where(x => x.ID == donationID)
            .SingleOrDefaultAsync();
    }

    public async Task AddDonationAsync(Donation donation)
    {
        await _context.Donations.AddAsync(donation);
    }

与使用

context.Set<>()
相同:

    public async Task<Donation?> GetDonationAsync(Guid donationID)
    {
        return await _context.Set<Donation>()
            .Where(x => x.ID == donationID)
            .SingleOrDefaultAsync();
    }

    public async Task AddDonationAsync(Donation donation)
    {
        await _context.Set<Donation>().AddAsync(donation);
    }

上面的代码包含在我的存储库服务中。我建议这样做并调用您的存储库,而不是直接调用您的数据库上下文。

示例

存储库示例

public class DonationRepository : IDonationRepository
{
    private readonly MyDatabaseContext _context;

    public DonationRepository(MyDatabaseContext context)
    {
        _context = context ?? throw new ArgumentNullException(nameof(context));
    }

    public async Task<Donation?> GetDonationAsync(Guid donationID)
    {
        return await _context.Donations
            .Where(x => x.ID == donationID)
            .SingleOrDefaultAsync();
    }

    public async Task AddDonationAsync(Donation donation)
    {
        await _context.Donations.AddAsync(donation);
    }

}

控制器示例

[ApiController]
[Route("[controller]")]
public class DonationController : Controller
{

    private readonly IDonationRepository _donationRepository;

    private readonly ILogger<DonationController> _logger;

    public DonationController(ILogger<DonationController> logger,
                            IDonationRepository donationRepository)
    {
        _logger = logger;
        _donationRepository = donationRepository;
        
    }

    [HttpGet]
    [Route("GetDonationValue")]
    public async Task<IActionResult> GetDonationValueAsync(Guid donationID)
    {

        var donation = await _donationRepository.GetDonationAsync(donationID);
        
        // Doesn't exist!
        if (donation == null) {
            _logger.LogError($"Couldn't find Donation with ID: '{donationID}'.");
            return NotFound();
        }
        
        _logger.LogInformation($"Found Donation with value of: '{donation.Amount}'.");          
        return Ok(donation.Amount);


    }

}
© www.soinside.com 2019 - 2024. All rights reserved.