2017-05-20 21 views
0

私はn層アプリケーションを開発していますが、データアクセスレイヤーでリポジトリパターンを使用することに決めましたが、ORMを使用したくありません(ADO .net)Entity Frameworkを使用しないリポジトリを使用したデータアクセスレイヤーの設計

2つのエンティティ(親の子関係ではない)の間に関係があるリポジトリのデータを取得する方法を決定できません。 私は顧客と注文表を持っています。 「顧客」テーブルにリンクされている「注文」テーブルには「顧客ID」列があります。私は受注コードに基づいて(単一または複数)受注
情報を取得していながら、顧客情報を取得する方法

  1. リポジトリのインスタンスを別のリポジトリに作成することはできますか?

以下は現在のコード構造です。

///////////// Abstract Class for Common Functionality//// 
public abstract class BaseRepository<T> where T : class 
{ 
    private static SqlConnection sqlConnection; 
    protected string DatabaseName { get; set; } 
    protected string ConnectionString; 
    public delegate T CallBack(SqlDataReader reader); 

    public BaseRepository() 
    { 
     ConnectionString = Convert.ToString(ConfigurationManager.ConnectionStrings["TestDB"]); 
     sqlConnection = new SqlConnection(ConnectionString); 
    } 

    protected abstract T PopulateRecord(SqlDataReader reader); 

    protected IEnumerable<T> GetRecords(SqlCommand command) 
    { 
     var list = new List<T>(); 
     using (SqlConnection connection = new SqlConnection(ConnectionString)) 
     { 
      command.Connection = connection; 
      connection.Open(); 

      using (SqlDataReader reader = command.ExecuteReader()) 
      { 
       if (reader != null) 
       { 
        while (reader.Read()) 
        { 
         list.Add(PopulateRecord(reader)); 
        } 
       } 
      } // reader closed and disposed up here 
     } //connection closed and disposed here 
     return list; 
    } 

} 

////////////////// Repository Class ////////////////////////// 

public class OrderRepository : BaseRepository<Order>, IRepository<Order> 
{ 
    protected override Order PopulateRecord(SqlDataReader reader) 
    { 
     return new Order 
     { 
      OrderID = reader.GetIntVal("OrderID"), 
      OrderDate = reader.GetDateTimeVal("OrderDate"), 
      ProductInfo= // How to Populate Product Information which is in another repository 
      CustomerInfo = // How to Populate Customer Information which is in another repository 
     }; 
    } 

    public IEnumerable<Order> GetAll() 
    { 
     SqlCommand cmd = new SqlCommand(); 
     cmd.CommandText = "GetOrders"; 
     cmd.CommandType = CommandType.StoredProcedure; 
     return GetRecords(cmd); 

    } 

} 

/////////////// Entity Class //////////////////// 
public class Order { 

    public int OrderID { get; set; } 
    public DateTime OrderDate { get; set; } 
    public Customer ProductInfo { get; set; } 
    public Product CustomerInfo { get; set; } 
} 

public class Customer { 

    public int CustomerID { get; set; } 
    public string CustomerName { get; set; } 
} 

public class Product { 

    public int ProductID { get; set; } 
    public string ProductName { get; set; } 
} 
+0

:一例として、あなたの質問を解決するには、この(工場と仮定すると、通常は注射し、プライベートな場である)ようなものになるだろう"any ORM"の代わりに使用しますか?適切なタグを適用します。質問にインラインでコードを投稿すると、それらのリンクはしばらくして死にます。 –

+0

はい。 ORMを使用せずにこのような設計を実装することは可能です。しかし、それは多くの作業になりますし、最終的に他のORMがやったことをやることになります。私は車輪を再発明しないでください。 Dapperのような軽量のマイクロORMの使用を検討してください。 –

+0

@AmitJoshi私はORMを再設計していません。バックエンドで私はCRUD操作のストアドプロシージャを記述しています。私は現在のコード構造を設計原則に従って改善したいと考えています。 –

答えて

0

以前の同僚と私はリポジトリパターンを実装するSqlRepoを作成しました。

注入されたファクトリからリポジトリを取得したら、コマンドを作成し、実用的なAPIと式を使用して実行してからエンティティを返すようにします。

単体テストはそれ自体ではかなり良い文書を形成しますが、それはまだ進行中の作業であり、ドキュメントには明るいですが質問に答えてもらえます。

http://github.com/testpossessed/sqlrepo

UPDATEでオーバー見てください:あなたは何

var customerRepository = this.repositoryFactory.Create<Customer>(); 
var customer = customerRepository.Query() 
           .Where(e => e.Id == 123) 
           .Go(); 

var orderRepository = this.repositoryFactory.Create<Order>(); 
customer.Orders = orderRepository.Query() 
           .Where(e => e.CustomerId == 123) 
           .Go(); 
+0

あなたは書かれたコードがリポジトリまたはBussiness Layerに配置されるべきであると私に教えてください(実際にはADO.netを使ってデータにアクセスしています)。 –

+0

私はあなたがビジネス層と言うだろうと思います。私は通常、このコードを含むUnitOfWorkコンポーネントを実装し、コントローラやビューモデルのような他のコンポーネントに注入します。 – testpossessed

+0

ドメインオブジェクトをリポジトリ自体に取り込みたいと思います。 –