实体框架 – 使用ASP.NET Web API和实体框架进行API版本控制

我正在使用ASP.NET Web API,Code-First Entity Framework 5和SQL Server 2012开发REST API,我需要能够对API进行版本控制.我已经阅读了一些博客文章和文章,关于在URI或自定义HTTP标头中指示API版本,并使用自定义IHttpControllerSelector根据指定的版本选择不同的ApiControllers.这一切都有道理.

我正在努力弄清楚的是如何管理Web API层以外的版本控制的影响,特别是在Entity Framework中.如何在不破坏旧版本API的情况下改进我的DbContext?我也可以对DbContext进行版本控制吗?如果是这样,怎么样?

最佳答案
我最终做的是将Repository Pattern与Pablo的答案结合起来.它的要点是我的EF模型是版本化的,我使用EF Code-First Migrations将数据库迁移到模型的新版本,我的DbContext始终使用最新版本的模型,我开发了许多具体的存储库每个实现IRepository< TItem>界面如下.

public interface IRepository<TItem> : IQueryable<TItem>, ICollection<TItem>, IDisposable
    where TItem : class
{
    void Update(TItem item);
    void SaveChanges();
}

IRepository< TItem>的一种实现方式.是DbRepository< TItem>它包装用于与数据库通信的实体框架代码.

public class DbRepository<TItem> : IRepository<TItem> 
    where TItem : class
{
    private MyDbContext _db;

    public DbRepository()
    {
        _db = new MyDbContext();
    }

    // Implementation of IRepository<TItem> methods
}

IRepository< TItem>的另一种实现方式.是TypeConversionRepository< TExternal,TInternal>这是一个抽象类,便于从一种模型类型转换为另一种模型类型.

public abstract class TypeConversionRepository<TExternal, TInternal> : IRepository<TExternal>
    where TExternal : class
    where TInternal : class
{
    protected IRepository<TInternal> InternalRepository { get; set; }

    protected abstract TInternal ConvertInbound(TExternal externalItem);

    protected abstract TExternal ConvertOutbound(TInternal internalItem);

    // Implementation of IRepository<TItem> methods
}

返回模型或接受模型作为参数的方法使用ConvertInbound()和ConvertOutbound()将TExternal类型的模型转换为TInternal,反之亦然.因此,给定以下2个版本的MyModel,我们可以编写2个版本的MyModelRepository;版本2可以直接与数据库通信,而版本1需要从版本2转换回版本1.

namespace Models.v1
{
    public class MyModel
    {
        public int Id { get; set; }
        public string MyProperty { get; set; }
    }

    public class MyModelRepository : TypeConversionRepository<Models.v1.MyModel,Models.v2.MyModel>
    {
        MyModelRepository()
        {
            this.InternalRepository = new Models.v2.MyModelRepository();
        }

        protected override TInternal ConvertInbound(TExternal externalItem)
        {
            return new Models.v2.MyModel
            {
                Id = externalItem.Id,
                MyNewProperty = externalItem.MyProperty
            };
        }

        protected override TExternal ConvertOutbound(TInternal internalItem)
        {
            return new Models.v1.MyModel
            {
                Id = internalItem.Id,
                MyProperty = internalItem.MyNewProperty
            };
        }
    }
}

namespace Models.v2
{
    public class MyModel
    {
        public int Id { get; set; }
        public string MyNewProperty { get; set; }
    }

    public class MyModelRepository : DbRepository<MyModel>
    {

    }
}

现在v1 ApiController可以使用v1 MyModelRepository,v2 ApiController可以使用v2 MyModelRepository,但最后所有请求都使用已迁移到v2的数据库.

转载注明原文:实体框架 – 使用ASP.NET Web API和实体框架进行API版本控制 - 代码日志