Skip to content
Rain Hu's Workspace
Go back

[IT] EntityFramework Commands

Rain Hu

前置作業

💡 Tip

若是實作的 DbContext 沒有合適的建構子,是無法進行 migration 的。

如果 DbContext 採用依賴注入的方式,且程式的 entry 又不在同一個專案底下,則需要覆寫 OnConfiguring() 來提供 Database 的連線資訊。

migration 指令

進行 Migration 初始化

dotnet ef migrations add InitialMigration -p src/CleanWebApi.Infrastructure
dotnet ef migrations add InitialCreate --startup-project src/CleanWebApi.Api --project src/CleanWebApi.Infrastructure

查詢 Migrations 清單

dotnet ef migrations list  -p src/CleanWebApi.Infrastructure

執行 Migration

dotnet ef database update InitialMigration -p src/CleanWebApi.Infrastructure

移除 Migration

dotnet ef migrations remove -p src/CleanWebApi.Infrastructure

清除 Database

dotnet ef database update 0 -p src/CleanWebApi.Infrastructure

⚠️ Warning

此指令會刪除 Database,若有重要資料,需先做好備份。

補充

抽象物件 Entity 實作

public interface IDomainEvent : INotification { }

public abstract class Entity
{
    public Guid Id { get; private init; }

    protected readonly List<IDomainEvent> _domainEvents = new();

    public Entity(Guid id)
    {
        Id = id;
    }

    public List<IDomainEvent> PopDomainEvents()
    {
        var copy = _domainEvents.ToList();
        _domainEvents.Clear();

        return copy;
    }

    protected Entity() { }
}

EventBus Middleware 的實作,用來將聚合根的 DomainEvents 進行推播。

public class EventualConsistencyMiddleware
{
    public const string DomainEventsKey = "DomainEventsKey";

    private readonly RequestDelegate _next; 

    public EventualConsistencyMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context, IPublisher publisher, AppDbContext dbContext)
    {
        var transaction = await dbContext.Database.BeginTransactionAsync();
        context.Response.OnCompleted(async () =>
        {
            try
            {
                if (context.Items.TryGetValue(DomainEventsKey, out var value) && value is Queue<IDomainEvent> domainEvents)
                {
                    while (domainEvents.TryDequeue(out var @event))
                    {
                        await publisher.Publish(@event);
                    }
                }

                await transaction.CommitAsync();
            }
            catch (Exception)
            {
            }
            finally
            {
                await transaction.DisposeAsync();
            }
        });

        await _next(context);
    }
}

Share this post on:

Previous
[IT] HTML + CSS
Next
[System Design] 系統設計概念與資源 System Design and Resources