locked
layred application mvc sales order and linq to entity RRS feed

  • Question

  • User-875744750 posted

    hello

    i'm beginner in repository and layerd application. and  i don't inderstand well which is the interaction and the relationship between the repositories and business layer classes.

     I have a confusion between both them

    Here is an example for purchaese order in 3 layers and I want to review whether correct or not, and your correction

    for DataAcesslayer

    repository OrderRepositolry

    Namespece Dal
        {
           Public class RepositoryOrder
           {
                  POrderContext context = new POrderContext ();
     
                  Public IEnumrebale <Order> GetAll ()
                  {
                       Context.Orders;
                  }
    // Following code
           }
        }

    for the item of order repositories code :

    namespece Dal
    {
          public class RepositoryOrderItem
          {
                 POrderContext context = new POrderContext();
    
                 public IEnumrebale<OrderItem> GetAllItemById(Order o)
                 {
                      context.OrderItems.where(i => i.OrderId == o.Id);
                 }
    
                public OrderItem GetItemById(int id)
                {
                     context.OrderItems.Find(id);
                }
    //Following code
          }
    }

    for businessLayer here is classOrderBLL code:

    namespace BLL
    {
          public class OrderBLL
          {
                RepositoryOrder repoOrder = new RepositoryOrder();
                RepositoryOrderItem repoItem = new  RepositoryOrderItem();
    
                public IList<Order> GetAll()
               {
                   return repoOrder.GetAll();
               }
    
                public decimal GetPrixTotal(Order order)
               {
                    var query = from item in repoItem.GetAllItemById(order)
                                     select sum(item=>item.Prix * item.Quantite);
                    return query;
                }
          }  
    }
    1. does the total price calculation is done at the level of repository or at the level of BLL (we can make this request linq with context in the repository)?

    2. CRUD method is done at repository and they are called at BLL from repository is it right?

    3. The where extension method or the where clause in the linq to entity query matches the business rule (will be implemented at BLL) or corresponds to the read data acess (at the repository level).

    Any help, advice and good practice will be welcome

    have a good day

    Saturday, March 11, 2017 3:02 PM

All replies

  • User-525215917 posted

    I would keep data related methods in repositories and return only already prepared data from there.

    Your current solution gives out IQueryable enumerables from repositories. It means that your data layer doesn't have much control over what is queried from database because database query is created when data is actually asked by application.

    My suggestion is - try to keep all querying related things in repository classes and don't let BLL level anarchy to happen.

    Tuesday, March 14, 2017 8:13 AM
  • User-821857111 posted

    I agree with Gunnar. 

    does the total price calculation is done at the level of repository or at the level of BLL (we can make this request linq with context in the repository)?

    I would have a repository method that returns the total. 

    CRUD method is done at repository and they are called at BLL from repository is it right?
    Yes. All data operations are done in the repository. 
    The where extension method or the where clause in the linq to entity query matches the business rule (will be implemented at BLL) or corresponds to the read data acess (at the repository level).
    You might shape the query in the business layer, but you should execute it in the data layer. You are currently defining a query in the data layer, but executing it in the business layer. That's what Gunnar refers to as BLL anarchy. 

    Don't forget, LINQ queries are only executed when you iterate the result explicitly (using foreach etc) or call ToList(), ToArray(), ToDictionary() etc on the query. 

    Tuesday, March 14, 2017 8:41 AM
  • User-875744750 posted

    hello

    Mikesdotnetting

    I would have a repository method that returns the total. 

    here is the code of repository methode that return the total. 

    namespece Dal
    {
          public class RepositoryOrderItem
          {
                 POrderContext context = new POrderContext();
    
                 public IEnumrebale<OrderItem> GetTotalOfAllItemById(Order o)
                 {
                      context.OrderItems.Sum(i => i.OrderId == o.Id);
                 }
    }

    Mikesdotnetting

    You might shape the query in the business layer, but you should execute it in the data layer. You are currently defining a query in the data layer, but executing it in the business layer. That's what Gunnar refers to as BLL anarchy. 

    please could you explaine more i don't inderstand

    for the things become clearer i suggest portion of code c# and l ask you for tell me what's the more correct

    1. for where() linq : the following code is it correct

    this code :  

    namespece Dal
    {
    
          public class RepositoryOrderItem
          {
    
                 POrderContext context = new POrderContext();
     
    
                 public IEnumrebale<OrderItem> GetAllItemById(Order o)
                 {
                      context.OrderItems.where(i => i.OrderId == o.Id);
    
                 }
           }
    }

     

        2. for count() linq : what's the more correct

    a. this code in repository 

    namespece Dal
    {
          public class RepositoryOrderItem
          {
                 POrderContext context = new POrderContext();
    
                 public IEnumrebale<OrderItem> GetNumberOfAllItemById(Order o)
                 {
                      context.OrderItems.Count(i => i.OrderId == o.Id);
                 }
    }


    or this in BLL

    namespace BLL
    {
          public class OrderBLL
          {
    
                RepositoryOrder repoOrder = new RepositoryOrder();
                RepositoryOrderItem repoItem = new  RepositoryOrderItem();
     
                public IList<Order> GetNumberOfAllItemById(Order order)
               {
    
                   return repoItem.GetAllItemById(order).Count();
    
               }
    }

    3.for insert methode

    namespece Dal
    {
          public class RepositoryOrder
          {
                 POrderContext context = new POrderContext();
    
                 public void InsertOrder(Order order)
                 {
                      context.Orders.Add(order);
                 }


    public void InsertOrderItem(Order order, OrderItem orderItem)
    {
    order.OrderItem.Add(orderItem);
    }
    }

      what's the best layer for viewmodel in this case?

    Tuesday, March 21, 2017 12:38 PM
  • User-821857111 posted

    1. for where() linq : the following code is it correct

    this code :  

    namespece Dal
    {
    
          public class RepositoryOrderItem
          {
    
                 POrderContext context = new POrderContext();
     
    
                 public IEnumrebale<OrderItem> GetAllItemById(Order o)
                 {
                      context.OrderItems.where(i => i.OrderId == o.Id);
    
                 }
           }
    }

     

    This is the equivalent of constructing a SQL query. The query itself is not executed here. It is only defined (or shaped). The query is only executed when ToList() or similar is added to the LINQ query. That is when data is returned. You should return data from your DAL (Repositories) so the code should look like this:

    public IEnumerable<OrderItem> GetAllItemById(Order o)
    {
        return context.OrderItems.where(i => i.OrderId == o.Id).ToList();
    
    }

    Tuesday, March 21, 2017 8:07 PM
  • User-821857111 posted

     2. for count() linq : what's the more correct

    a. this code in repository 

    namespece Dal
    {
          public class RepositoryOrderItem
          {
                 POrderContext context = new POrderContext();
    
                 public IEnumrebale<OrderItem> GetNumberOfAllItemById(Order o)
                 {
                      context.OrderItems.Count(i => i.OrderId == o.Id);
                 }
    }


    or this in BLL

    namespace BLL
    {
          public class OrderBLL
          {
    
                RepositoryOrder repoOrder = new RepositoryOrder();
                RepositoryOrderItem repoItem = new  RepositoryOrderItem();
     
                public IList<Order> GetNumberOfAllItemById(Order order)
               {
    
                   return repoItem.GetAllItemById(order).Count();
    
               }
    }

    The DAL should return data:

    namespece Dal
    {
          public class RepositoryOrderItem
          {
                 POrderContext context = new POrderContext();
    
                 public int GetNumberOfAllItemById(Order o)
                 {
                      context.OrderItems.Count(i => i.OrderId == o.Id);
                 }
    }
    Tuesday, March 21, 2017 8:08 PM