12

現在、 ASP.NET MVC 5プロジェクトに取り組んでおり、プロジェクトのアーキテクチャを磨こうとしています。将来、人々ができるだけクリーンで簡単に作業できるようにします。

手始めに、EntityFrameworkモデル (IdentityUser と AccountViewModel を含む) を同じソリューション内のクラス ライブラリ プロジェクトに移動しました。これは現在、メインの MVC プロジェクトによって参照されています。

ただし、現在、DbContext (複数の DbContext を使用する場合は DbContext) とデータ アクセス レイヤーを保持する新しいデータ アクセス レイヤー プロジェクトを作成することを検討しています。これを行うための最良の方法は何ですか?

この DAL プロジェクトは Model プロジェクトを参照し、メイン MVC プロジェクトは DAL プロジェクトのみを参照します。

この記事を読んだら!EntityFrameworkを使用する場合、リポジトリパターンが実際に廃止されているかどうか疑問に思っていました。

だから私の2つの主な質問は次のとおりです。

1)DALを別のプロジェクトに引き出す最良の方法は何ですか

2)EFを使用してデータベースコンテンツにアクセスする最良の方法は何ですか

4

1 に答える 1

8

あなたの質問はかなり広いです。たとえば、「EF を使用してデータベース コンテンツにアクセスする最良の方法」とはどういう意味ですか? パフォーマンスの面で最良の方法は?

リポジトリパターンを使用する、私が好むオプション (ほとんどの場合、いくつかのバリアントを使用します) を指定して答えようとします。EF セットをリポジトリとして直接使用する場合、リポジトリ パターンは必要ないと主張するかもしれませんが、私はそれらを独自のものにラップするのが好きです。

あなたの言いたいことがよくわからないので、一般的な Web プロジェクトに適した個人的な好みを示します。

完全に機能するようにすべてのコードを投稿するつもりはありませんが、何が起こっているのかを明確に理解できるはずです。

セットアップ (4 つのプロジェクト):

UI ----------> Domain.Logic (w. Domain.Models) ------> データ (EF コンテキストを保持)。

データ:

public partial class EFContextContainer : DbContext 
enter code here
public EFContextContainer ()
        : base("name=EFContextContainer")
    {
    }

public DbSet<IdentityUser> IdentityUsers { get;set; } 

コンテキストを返すラッパーを使用:

public static class Database
{
    public static EFContextContainerGetContext()
    {
        return new EFContextContainer();
    }

}

次のようにリポジトリをセットアップできます。

インターフェース:

public interface IRepository<T> where T : class
{
    IQueryable<T> GetAll();
    T GetById(Guid id);
    void Add(T entity);
    void Update(T entity);
    void Delete(T entity);
    void Delete(Guid id);
}

実装 (簡潔にするために Add(T エンティティ) のみを実装):

public class EFRepository<T> : IRepository<T>, IDisposable where T : class
{
    public EFRepository(DbContext dbContext)
    {
        if (dbContext == null)
            throw new ArgumentNullException("dbContext");
        DbContext = dbContext;
        DbSet = DbContext.Set<T>();

    }

    protected DbContext DbContext { get; set; }

    protected DbSet<T> DbSet { get; set; }

    public virtual void Add(T entity)
    {
        DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
        if (dbEntityEntry.State != EntityState.Detached)
        {
            dbEntityEntry.State = EntityState.Added;
        }
        else
        {
            DbSet.Add(entity);
        }
    }

public void Dispose()
    {
        DbContext.Dispose();
    }

}

ドメイン:

Domain.Logic (IdentityUserManager は Domain.Models のクラスになります):

public class IdentityUserManager
{
    public void Add(IdentityUser idUser)
    {
        using(var idUserRepository = new EFRepository<IdentityUser>(Database.GetContext())
        {
            idUserRepository.Add(idUser);
        }
    }
}

UI:

[HttpPost]
public ActionResult Post(UserViewModel model)
{
    UserIdentity user = MapUser(model);
    var userManager = new IdentityUserManager();
    userManager.Add(user);

    return View(new UserViewModel());
}

(これはすべて Visual Studio で構成されているわけではないため、スペルミスがある場合はご容赦ください。)

確かに、このコードにはさらに多くの抽象化が含まれている可能性がありますが、ここでソリューション全体を書き留めるのはばかげています。たとえば、Unit of Workパターンも使用できます。これは、リポジトリ パターンとうまく連携します。したがって、これは一例であり、このセットアップの実装方法に関する完全なガイドではありません。この例よりもはるかにきれいにセットアップできます。

これらのパターンの実装の詳細については、Plural Sight の John Papa によるコースSingle Page Appsを参照することをお勧めします。彼は、これらのパターンの利点とその実装方法を見事に説明しています。

于 2013-10-29T10:10:16.400 に答える