web-dev-qa-db-ja.com

エンティティフレームワーク5、ビジネスロジックをモデルから分離-リポジトリ?

私は最初の公開Webアプリケーションに取り組んでおり、プレゼンテーションレイヤーにMVC 4を、DALにEF 5を使用しています。データベース構造はロックされており、ユーザーがデータを入力する方法とデータベース自体にデータが入力される方法には適度な違いがあります。私はリポジトリパターン(これまで使用したことがない)を大量に読みましたが、リポジトリとユニット以降のEFの最新バージョンに不必要なレベルの抽象化を作成するため、私の研究のほとんどは私を使用から遠ざけています。 of-workはすでに組み込まれています。

私の最初のアプローチは、コントローラーとDALの間の仲介役として機能するBLL内のビジネスオブジェクト用に別個のクラスセットを作成することです。次にクラスの例を示します。

public class MyBuilding
{
    public int Id { get; private set; }
    public string Name { get; set; }
    public string Notes { get; set; }

    private readonly Entities _context = new Entities(); // Is this thread safe?
    private static readonly int UserId = WebSecurity.GetCurrentUser().UserId;

    public IEnumerable<MyBuilding> GetList()
    {
        IEnumerable<MyBuilding> buildingList = 
            from p in _context.BuildingInfo
            where p.Building.UserProfile.UserId == UserId
            select new MyBuilding {Id = p.BuildingId, Name = p.BuildingName, Notes = p.Building.Notes};
        return buildingList;
    }

    public void Create()
    {
        var b = new Building {UserId = UserId, Notes = this.Notes};
        _context.Building.Add(b);
        _context.SaveChanges();

        // Set the building ID
        this.Id = b.BuildingId;

        // Seed 1-to-1 tables with reference the new building
        _context.BuildingInfo.Add(new BuildingInfo {Building = b});
        _context.GeneralInfo.Add(new GeneralInfo {Building = b});
        _context.LocationInfo.Add(new LocationInfo {Building = b});
        _context.SaveChanges();
    }

    public static MyBuilding Find(int id)
    {
        using (var context = new Entities())  // Is this OK to do in a static method?
        {
            var b = context.Building.FirstOrDefault(p => p.BuildingId == id && p.UserId == UserId);
            if (b == null) throw new Exception("Error: Building not found or user does not have access.");
            return new MyBuilding {Id = b.BuildingId, Name = b.BuildingInfo.BuildingName, Notes = b.Notes};
        }
    }
}

私の主な関心事:DbContextをプライベートプロパティとしてインスタンス化する方法はスレッドセーフですか?また、別のDbContextをインスタンス化する静的メソッドを使用しても安全ですか?それとも私はこれをすべて間違っていますか?ここで完全に間違ったアプローチをとっていても、リポジトリパターンについて学ぶことに反対していません。

2
bnice7

データベーススキーマは範囲外であり、変更される可能性があるため、メインコードベースから分離することが非常に重要です。 CreateおよびGetList関数から呼び出すマッピング操作とテーブル操作操作は、理想的にはDALに常駐する必要があります。これにより、エンティティとビジネスロジッククラスは、EFで生成されたコードへの予期しない変更の影響を受けなくなります。データベーススキーマに対する大きな変更でさえ、マッピング機能を変更するだけの問題になります。

それ以外の場合は、自分のタイプの他のインスタンスをロードする呼び出しを持つビジネスエンティティインスタンスは避けます。MyBuikdingインスタンスはデータファインダーオブジェクトとデータエンティティの両方であるため、単一責任の原則違反の匂いがします。 DALリポジトリへの呼び出しからエンティティを直接取得することも、ビジネスロジックが必要な場合はいくつかの中間サービスレイヤー呼び出しを介して取得することもできます。

3
Mr Cochese