2017-05-20 4 views
0

Je développe une application n-tier et j'ai décidé d'utiliser le Repository Pattern dans Data Access Layer mais je ne veux utiliser aucun ORM (va utiliser ADO .net)Conception de la couche d'accès aux données en utilisant Repository sans utiliser Entity Framework

Je ne suis pas capable de décider comment récupérer les données dans le référentiel où il y a une relation entre 2 entites (pas de relation parent-enfant). Par exemple. J'ai la table de commande et de client. Il y a une colonne "CustomerID" dans la table "Order" qui est liée à la table "Customer".

  1. Comment récupérer les informations du client pendant que je suis aller chercher Commandes
    information (simple ou multiple) basé sur OrderID?
  2. Pouvons-nous utiliser create instance d'un dépôt dans un autre?

Voici la structure de code actuelle.

///////////// 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

Que voulez-vous utiliser au lieu de "n'importe quel ORM"? appliquer les bonnes étiquettes. Post (parties de) le code en ligne dans la question, ces liens disparaissent après un certain temps. –

+0

Oui; il est possible de mettre en œuvre une telle conception SANS utiliser d'ORM. Mais ce sera beaucoup de travail et vous ferez enfin ce que les autres ORM ont fait. Je recommande s'il vous plaît ne pas réinventer la roue. Envisagez d'utiliser un micro-ORM léger comme Dapper. –

+0

@AmitJoshi Je ne suis pas en train de repenser un ORM. Sur le backend j'écris la procédure stockée pour des opérations de CRUD. Je veux améliorer ma structure de code actuelle en suivant les principes de conception. –

Répondre

0

Un ancien collègue et j'ai créé SqlRepo qui implémente le modèle du référentiel. Une fois que vous obtenez un référentiel d'une usine injectée, vous créez une commande et utilisez une API et des expressions fluides pour générer la requête avant de l'exécuter pour renvoyer des entités.

Il s'agit d'un travail en cours et léger sur la documentation, mais heureux de répondre aux questions, bien que les tests unitaires forment une bonne documentation à part entière.

Jetez un oeil sur au http://github.com/testpossessed/sqlrepo

MISE À JOUR: À titre d'exemple la solution à votre question serait quelque chose comme ça (en supposant l'usine est un champ privé, généralement injecté):

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

Pourriez-vous s'il vous plaît me dire ci-dessus le code écrit doit être placé dans le dépôt ou dans Bussiness Layer? (Par la façon dont j'utilise ADO.net simple pour accéder aux données). –

+0

Je suppose que vous diriez la couche de gestion. J'implémente habituellement les composants UnitOfWork qui incluent ce code, puis les injecte dans d'autres composants comme Controllers ou View Models – testpossessed

+0

Je veux remplir mon objet domaine dans le référentiel lui-même. –