locked
update master with sum record of details RRS feed

  • Question

  • User-875744750 posted

    hello

    i have created solution in visual studio 2012 and this solution is layred in 4 project :

    1. project presentation layer (asp.net mvc) 

    2. business entities layer

    public class Master
    {
       public int Id {get; set;}
       public decimal TotalPrice {get; set;}
       //the rest of properties
       public private ICollection<Detail> Details {get; set;}
    }
    
    public class Detail
    {
      public int Id {get; set;}
      public decimal UnitePrice {get; set;}
       //the rest of properties
      public int MasterId {get; set;}
      public private Master Master {get; set;}
    }
    

    3. data access layer (ado.net data model entity framework + repositories)

    public class MasterRepository : IMasterRepository{
        //code of class to implemente GetAll + CRUD for master
    }
    
    
    public class DetailRepository : IDetailRepository{
        
       EFContext context = new EFContext();
    
      //Get the details for one master
    
       public IEnumerable<Detail> GetAllDetailsByMasterId(int masterId)
       {
          var query = context.Details.Where(d=>d.MasterId == masterId)
       }
    
      //the rest of code to implemente CRUD of details
    
    }

    4. but for business logic layer in classes Bll i try to calculate the total of the master by sum of unit prices for the details

    public class MasterDetailsBll
    {
    
       public decimal GetTotal(){
    
    //call the methode GetAllDetailsByMasterId of DetailRepository thet return enumerebal<detail> and then call the extention methode Sum for calculate the sum of unite prices of detail
          
           using (var repository = new DetailRepository())
           {       
             var total = reopsitory.GetAllDetailsByMasterId(masterId).Sum(d=>d.UnitePrice);
           }

    //call the CRUD Mehodes of repositoryMaster and CRUD of the repositoryDetails } }

    I am a beginner in .net and I do not know if working with a layered application is a good idea or not.

    How I update total of master with sum of unit price after each insert/update of detail?

    please help me

    Friday, September 15, 2017 2:58 PM

All replies

  • User1120430333 posted

    I am a beginner in .net and I do not know if working with a layered application is a good idea or not.

    Yes, it' a good idea. :)

    https://en.wikipedia.org/wiki/Separation_of_concerns

    http://www.dotnet-stuff.com/tutorials/c-sharp/understanding-loose-coupling-and-tight-coupling

    https://msdn.microsoft.com/en-us/library/bb384398.aspx

    data access layer (ado.net data model entity framework + repositories)

    The repository sits between the BLL and the DAL.

    https://msdn.microsoft.com/en-us/library/ff649690.aspx

    The repository can do business functions and is not solely dedicated to CRUD operations with the DB. The repository can call on the DAO  in the DAL for CRUD operations with the DB, call other repertory objects for business needs, call services etc. and ect.  

    http://blog.sapiensworks.com/post/2012/11/01/Repository-vs-DAO.aspx

    If the BLL is just a passthrough and so anemic that it's doing nothing, then you can make the call to the repository and eliminate the BLL.

    https://www.tutorialspoint.com/design_pattern/data_access_object_pattern.htm

    You should leave the EF entities at the DAL and send the DTO as a single DTO or DTO(s) in a List<T> mapping DTO to entity and vise versa. You can put the DTO(s) is a project called Entities and all projects set reference to entities and know what the DTO(s) are about.

    https://juristr.com/blog/2012/10/lessions-learned-dont-expose-ef-entities-to-the-client-directly/

    https://www.codeproject.com/Articles/1050468/Data-Transfer-Object-Design-Pattern-in-Csharp

    If you are using EF Code first, then maybe it could be best that you switch to DB first and not let Code first burn you.

    https://entitiestodtos.codeplex.com/

    Make the changes to your solution architecture, if you choose to do so.

    fyi...

    http://www.c-sharpcorner.com/UploadFile/56fb14/understanding-separation-of-concern-and-Asp-Net-mvc/

    DAL using DAO  pattern with EF DB first that is called by the Repository object. 

    using System;
    using System.Collections.Generic;
    using Entities;
    
    namespace DAL.DAO
    {
        public interface IDAOStudent
        {
            DTOStudent GetStudentById(Int32 id);
            List<DTOStudent> GetStudents();
            void CreateStudent(DTOStudent dto);
            void UpdateStudent(DTOStudent dto);
            void DeleteStudent(Int32 id);
        }
    }
    ----------------------------------------
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Data.Entity;
    using Entities;
    using DAL.Model;
    
    namespace DAL.DAO
    {
        public class DAOStudent : IDAOStudent
        {
            public DTOStudent GetStudentById(Int32 id)
            {
                var dto = new DTOStudent();
                using (var context = new CUDataEntities())
                {
                    var student = (context.Students.Where(a => a.StudentID == id)).SingleOrDefault();
    
                    if (student != null)
                    {
                        dto.StudentID = student.StudentID;
                        dto.FirstName = student.FirstName;
                        dto.LastName = student.LastName;
                        dto.EnrollmentDate = student.EnrollmentDate;
    
                        var enrolllments =  new DAOEnrollment().GetEntrollmentsByStudentId(id).ToList();
                        var courses = new DAOCourse().GetCoursesByStudentCourseId(student.StudentID).ToList();
    
                        dto.EnrollsandCourses = (from a in enrolllments
                                      join b in courses on a.CourseID equals b.CourseID
                        select new  DTOEnrollandCourse()
                         { Title = b.Title, Credits = b.Credits, Grade = a.Grade }).ToList();
                    }
                }
    
                return dto;
            }
            public void CreateStudent(DTOStudent dto)
            {
                using (var context = new CUDataEntities())
                {
                    var student = new Student
                    {
                        FirstName = dto.FirstName,
                        LastName = dto.LastName,
                        EnrollmentDate = dto.EnrollmentDate
                    };
    
                    context.Students.Add(student);
                    context.SaveChanges();
                }
            }
    
            public void DeleteStudent(int id)
            {
                Student student;
                using (var context = new CUDataEntities())
                {
                    student = (context.Students.Where(a => a.StudentID == id)).SingleOrDefault();
                }
    
                using (var newContext = new CUDataEntities())
                {
                    newContext.Entry(student).State = System.Data.Entity.EntityState.Deleted;
                    newContext.SaveChanges();
                }
            }
    
            public List<DTOStudent> GetStudents()
            {
                var dtos = new List<DTOStudent>();
    
                using (var context = new CUDataEntities())
                {
                    var students = context.Students.ToList();
    
                    foreach(var stud in students)
                    {
                        var dto = new DTOStudent
                        {
                            StudentID = stud.StudentID,
                            FirstName = stud.FirstName,
                            LastName = stud.LastName,
                            EnrollmentDate = stud.EnrollmentDate
                        };
    
                        dtos.Add(dto);
                    }
                }
    
                return dtos;
            }
    
            public void UpdateStudent(DTOStudent dto)
            {
                var student = new Student();
    
                using (var context = new CUDataEntities())
                {
                    student = (context.Students.Where(a => a.StudentID == dto.StudentID)).SingleOrDefault();
                }
    
                if (student != null)
                {
                    student.FirstName = dto.FirstName;
                    student.LastName = dto.LastName;
                    student.EnrollmentDate = dto.EnrollmentDate;
                } 
    
                using (var dbcontext = new CUDataEntities())
                {
                    if (student != null)
                    {
                        dbcontext.Entry(student).State = EntityState.Modified;
                        dbcontext.SaveChanges();
                    }
                }
            }
        }
    }
    

    Friday, September 15, 2017 4:00 PM
  • User-875744750 posted

    Thank you for your advice, guidance and your help, I'm happy

    but one question still there

       How I update total of master with sum of unit price after each insert/update/delete of detail?

    soon

    Friday, September 15, 2017 5:50 PM
  • User1120430333 posted

    After you do the insert/update/delete of the child detail objects in the children collection belonging to the master and the persistence is done, then you can read all the child detail objects if you have the foreign-key property exposed in the child entity,  where you take the ID of the master and query for all children objects linked to the parent by foreign-key id property in the child collection.

    var unitpricesum = (from a in db.childtable

                                    Where a.child_forign_key_property == held_master_ID select a.unitprice).Sum();

    https://code.msdn.microsoft.com/LINQ-Aggregate-Operators-c51b3869

    Then you update master with unitpricesum, which it all can be done in the DAOMaster, right?

    if using the DTO pattern, then EF is in a disconnected state and you have to deal with it.

    http://www.entityframeworktutorial.net/EntityFramework5/attach-disconnected-entity-graph.aspx

      

    Friday, September 15, 2017 9:21 PM
  • User-875744750 posted

    Hello again

    thank you but I did not understand what the relationship between your articles and calculations of sum of details records

    what if i wante to update total of master when each one detail have been inserted /updated/deleted, and not all details of master?

    what if i used repository for master and repository of details ? and if these repositories implements IDisposable, how to use the tow repositories with each their save methode  to updating master total with unitprice of this detail in DTO pattern and class BLL

    goodbye

    Sunday, September 17, 2017 10:15 AM
  • User1120430333 posted

    Hello again

    thank you but I did not understand what the relationship between your articles and calculations of sum of details records

    what if i wante to update total of master when each one detail have been inserted /updated/deleted, and not all details of master?

    what if i used repository for master and repository of details ? and if these repositories implements IDisposable, how to use the tow repositories with each their save methode  to updating master total with unitprice of this detail in DTO pattern and class BLL

    goodbye

    I suggest that you not use the Repository in the manner in which you are using it, which is in the DAL. The Repository is moved into a separate project called the Repository and all Repository objects are in the Repository project.. The Repository project has reference to the DAL and the RepostoryMaster calls the DAOMaster that does the CRUD operations using EF.

    1) There is no reason that the RepositoryMaster  object cannot call the RepositoryDetail object passing the Master's ID  calling a method that gets all the Detail by Master ID from the DAODetail,  sums all the Datails, could be DTO(s) or not,  for the given Maser ID and returns the SUM out of the method to be used by the RepositoryMaster to update the Master when DAOMaster object method using the Sum is called.

    Of course option 1 would be done after the Master and Detail objects, using a DTO container that had DTOMaster and a List<DTODetail> within the container  the was sent to the client, manipulated by the client and the DTO container  sent to the DAL using DAOMaster to persist the Master and the Detail.

    Now it's up to you to determine how the DTOContainer holding the DTOMaster and List<DTODetail> that was sent to the client is persisted to the DB

    2) by Detail sent over to the RepositoryDetail to persist the Detail from the RepositoryMaster

    3) Send the DTOcontainer into the DAOMaster from the RepositoryMaster, persist the Master and Detail within the DAOMaster,  or DAOMaster sends the Detail over to DAODetail to persist the Detail.

    If the BLL is doing nothing, it has no business logic and is being used as a pass-through from the client to the Repository, then why not call the Repository from the client and eliminate the BLL.

    Where does it say they the Repository must use IDisposable? Just because it's written somewhere does it mean it has to be done! :)

    Repository object calling the DAL DAO.

    using System;
    using System.Collections.Generic;
    using Entities;
    
    namespace Repository
    {
        public interface IStudentRepo
        {
            DTOStudent GetStudentById(Int32 id);
            List<DTOStudent> GetStudents();
            void CreateStudent(DTOStudent dto);
            void UpdateStudent(DTOStudent dto);
            void DeleteStudent(Int32 id);
        }
    }
    
    ------------------------------------------------------------------------------------
    
    using System;
    using System.Collections.Generic;
    using Entities;
    using DAL.DAO;
    
    namespace Repository
    {    public class StudentRepo : IStudentRepo
        {
            private IDAOStudent _daoStudent;
    
            public StudentRepo(IDAOStudent daoStudent)
            {
                _daoStudent = daoStudent;
            }
            public DTOStudent GetStudentById(int id)
            {
               return _daoStudent.GetStudentById(id);
            }
            public List<DTOStudent> GetStudents()
            {
                return _daoStudent.GetStudents();
            }
            public void CreateStudent(DTOStudent dto)
            {
                _daoStudent.CreateStudent(dto);
            }
            public void UpdateStudent(DTOStudent dto)
            {
                _daoStudent.UpdateStudent(dto);
            }
            public void DeleteStudent(int id)
            {
                _daoStudent.DeleteStudent(id);
            }
        }
    }
    

     

    Sunday, September 17, 2017 1:12 PM