使用大众运输库时实体框架核心不起作用

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

我有一个项目,以前的 ef 命令(例如 add-migration 和 update-database)工作正常。 但我做了一些事情之后这些命令就不再起作用了。

1- 添加 Resharper 插件。即使禁用此插件,这些命令仍然不起作用。此外,我做了一个测试项目,使用这个插件,这些命令可以正常工作。

2- 创建一个新的 C# 库。我创建了一个文件夹并构建了库,但库不是构建在文件夹中,而是构建在根目录中。我删除了文件夹和库,sln文件中没有这个库的痕迹。

3- 将所有 ef 库从版本 8.0.2 更新到 8.0.3

在我的解决方案中,有几个 C# 库,每个库都有自己的 DbContext (cqrs)。在与Command相关的主项目中,有一个名为ContentCommandDbContext的DbContext,在8.0.2版本中,我创建了另一个名为ContentCommandDbContextFactory的DbContext,它继承自IDesignTimeDbContextFactory并修复了错误。

我现在遇到的问题是,我在 PackageManagerConsule 窗口中执行的每个 ef 命令在项目构建后都不会发生,并且程序仍然在后台运行并且不会创建脚本。它会一直在后台运行,直到我重新启动计算机。

但是当我通过 CLI 执行命令时,它是正确完成的。

有谁知道问题出在哪里以及如何修复它以便我可以像以前一样使用 vs 2022?

----------更新----------

我发现问题了。问题出在 IPublishEndpoint 在我的自定义拦截器中。当我删除与 IPublishEndpoint 相关的部分时,命令可以正常工作。

即使我使用CLI命令创建数据库,当程序想通过ef core8保存数据时,程序仍然无法运行。

 public class DomainEventsDispatcherInterceptor : SaveChangesInterceptor
{
    private readonly IMediator _mediator;
    private readonly IPublishEndpoint _publishEndpoint;
    //todo using masstransit here
    public DomainEventsDispatcherInterceptor(IServiceProvider serviceProvider)
    {
        _publishEndpoint = serviceProvider.GetRequiredService<IPublishEndpoint>();
        _mediator = serviceProvider.GetRequiredService<IMediator>();
    }

    public override async ValueTask<int> SavedChangesAsync(SaveChangesCompletedEventData eventData, int result,
        CancellationToken cancellationToken = default)
    {
        var affectedRows = await base.SavedChangesAsync(eventData, result, cancellationToken);

        if (affectedRows > 0)
        {
            var aggregateRoots =
                    eventData.Context?.ChangeTracker.Entries()
                        .Where(current => current.Entity is IAggregateRoot)
                        .Select(current => current.Entity as IAggregateRoot)
                        .ToList()
                ;

            foreach (var aggregateRoot in aggregateRoots)
            {
                // Dispatch Events!
                if (aggregateRoot != null)
                {
                    foreach (var domainEvent in aggregateRoot.DomainEvents)
                    {
                        //  await _mediator.Publish(domainEvent, cancellationToken);
                        await _publishEndpoint.Publish(domainEvent, cancellationToken); //albate domain event ehtenmalan moshkel darad bayad dar eventbus.message bashad baraye namespace ha ke dar masstransit mohem hastand
                                                                                        //add masstransit
                    }

                    // Clear Events!
                    aggregateRoot.ClearDomainEvents();
                }
            }
        }
        return affectedRows;
    }

    public override int SavedChanges(SaveChangesCompletedEventData eventData, int result)
    {
        var affectedRows = base.SavedChanges(eventData, result);
        if (affectedRows > 0)
        {
            var aggregateRoots =
                    eventData.Context?.ChangeTracker.Entries()
                        .Where(current => current.Entity is IAggregateRoot)
                        .Select(current => current.Entity as IAggregateRoot)
                        .ToList()
                ;

            foreach (var aggregateRoot in aggregateRoots)
            {
                // Dispatch Events!
                if (aggregateRoot != null)
                {
                    foreach (var domainEvent in aggregateRoot.DomainEvents)
                    {
                        //_mediator.Publish(domainEvent);
                        _publishEndpoint.Publish(domainEvent); //albate domain event ehtenmalan moshkel darad bayad dar eventbus.message bashad baraye namespace ha ke dar masstransit mohem hastand
                    }

                    // Clear Events!
                    aggregateRoot.ClearDomainEvents();
                }
            }
        }
        return affectedRows;
    }

下面的代码是Program.cs文件中的设置:

...
//add command dbcontext
builder.Services.AddDbContext<ContentCommandDbContext>((serviceProvider, options) =>
{
    options.UseSqlServer(cnn, option =>
    {
        option.EnableRetryOnFailure(6);
        option.MinBatchSize(1);
    });
    options.AddInterceptors(new IInterceptor[]
    {
        new DomainEventsDispatcherInterceptor(serviceProvider)
    }); ;
});
//add query dbcontext
builder.Services.AddDbContext<ContentQueryDbContext>(c => c.UseSqlServer(cnn));
....

builder.Services.AddMassTransit(x =>
{
    x.AddEntityFrameworkOutbox<ContentCommandDbContext>(o =>
    {
        o.QueryDelay = TimeSpan.FromSeconds(1);

        o.UseSqlServer();
        o.UseBusOutbox();
    });
    //The outbox can also be added to all consumers using a configure endpoints callback:
    // https://masstransit.io/documentation/configuration/middleware/outbox
    x.AddConfigureEndpointsCallback((context, name, cfg) =>
    {
        cfg.UseEntityFrameworkOutbox<ContentCommandDbContext>(context);
    });

    x.UsingRabbitMq((context, cfg) =>
    {
        cfg.Host("amqp://guest:guest@localhost:5672 ");
        cfg.AutoStart = true;
        cfg.ReceiveEndpoint("queue-name", c => c.ConfigureConsumers(context));
    });
    x.AddConsumers(typeof(CommentAddedEvent).Assembly, typeof(CommentAddedEventHandler).Assembly);
});
...

有人可以指导我,问题出在哪里吗?

c# visual-studio entity-framework-core masstransit ef-core-8.0
1个回答
0
投票

我找到了答案。我应该使用 IBus 而不是 IPublishEndpoint。

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