2013-02-13 12 views
5

ASP.NET Web API、Code-First Entity Framework 5、SQL Server 2012を使用してREST APIを開発しており、APIをバージョンアップする必要があります。私は、いくつかのブログ記事と、APIバージョンをURIまたはカスタムHTTPヘッダーに指定する方法と、カスタムIHttpControllerSelectorを使用して、指定されたバージョンに基づいて異なるApiControllerを選択する方法についての記事を読んだ。これはすべて意味があります。ASP.NET Web APIとEntity Frameworkを使用したバージョン管理

私は、Web APIレイヤーを越えて、特にEntity Frameworkのバージョン管理の影響をどのように管理するのが苦労しているのですか。以前のバージョンのAPIを破棄せずにDbContextを進化させるにはどうすればよいですか? DbContextもバージョンアップできますか?そしてもしそうなら、どうですか?

答えて

3

私がやったのは、Repository PatternとPabloの答えを組み合わせたことでした。その要点は、私のEFモデルがバージョン化されていることです。私はEFコード一次移行を使用してデータベースをモデルの新しいバージョンに移行します。私のDbContextは常に最新バージョンのモデルで動作します。それぞれ下記のIRepository<TItem>インターフェイスを実装しています。 IRepository<TItem>

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

一の実装では、データベースと対話するために使用されるエンティティ・フレームワーク・コードをラップ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>あります。モデルを返すかのパラメータがTInternal及びその逆にタイプTExternalのモデルを変換するConvertInbound()ConvertOutbound()を使用するようにモデルを受け入れる

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 
} 

方法。したがって、次の2つのバージョンのMyModelがある場合、MyModelRepositoryの2つのバージョンを作成できます。バージョン2は、バージョン1は、今のV1 ApiControllerがV2のApiControllerがV2のMyModelRepositoryを使用することができ、V1のMyModelRepositoryを使用することができます。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> 
    { 

    } 
} 

バック版にバージョン2から変換する必要がありますしながら、データベースに直接話をすることができますが、最後にすべての要求はv2に移行されたデータベースを利用します。

1

ウェブAPIとアンダーラインDBモデルを別々に(あるいはEFモデル)進化させるのがよい方法だと思います。つまり、Web APIのDTFモデルで、Web APIのEFモデルにマップされます。インダイレクションのレイヤーは、おそらくWeb APIまたはEFモデルにのみ影響する変更を加える機会を与えます。さらに、Web APIの新しいバージョンは、既存のEFモデルに直接影響を与えない可能性があります。たとえば、まったく異なるテーブル・セットを使用する新しいバージョンのWeb APIです。

よろしく、 パブロ。

関連する問題