none
repository-amp-windowsform

All replies

  • Hi Ali_Lonbar,

    Thank you for posting here.

    Since your question is more related to EF, I will move it to ADO.NET Entity Framework and LINQ to Entities forum.

    https://social.msdn.microsoft.com/Forums/en-US/home?forum=adodotnetentityframework&filter=alltypes&sort=lastpostdesc

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, April 22, 2019 7:37 AM
  • The Repository pattern is not a persistence pattern. The Repository pattern is a domain pattern, which is being used erroneously due to the  generic Repository pattern used by developers.

    https://martinfowler.com/eaaCatalog/repository.html

    <copied>

    A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes. Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer. Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers.

    <end>

    https://programmingwithmosh.com/net/common-mistakes-with-the-repository-pattern/

    (https://blog.sapiensworks.com/post/2012/03/05/The-Generic-Repository-Is-An-Anti-Pattern.aspx)

    (https://www.infoworld.com/article/3117713/design-patterns-that-i-often-avoid-repository-pattern.html)

    The pattern you most likely should be using is the DOA pattern, paticularly if the Repositroy is anemic of any domain logic.

    (https://blog.sapiensworks.com/post/2012/11/01/Repository-vs-DAO.aspx)

    (https://en.wikipedia.org/wiki/Data_access_object)

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

    Example code below of Data Access Layer (DAL) using the DAO and DTO patterns, along with EF. The DTO(s) are kept in a classlib project called Entities, and they  are sent through the layers, leaving the EF entities at the DAL.

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

    You also might want to look into using the MVP pattern with your Windows form project, which is the presentation layer in Layered Architectural Style.

    (https://www.codeproject.com/Articles/228214/Understanding-Basics-of-UI-Design-Pattern-MVC-MVP)

    (http://polymorphicpodcast.com/shows/mv-patterns/)

    (https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ee658117(v=pandp.10))

    (https://www.codeproject.com/Articles/36847/Three-Layer-Architecture-in-C-NET)

    using System;
    using System.Collections.Generic;
    using System.Text;
    using Entities;
    
    namespace DAL
    {
        public interface IDaoProject
        {
            DtoProject GetProjectById(int id);
            List<DtoProject> GetProjectsByUserId(string userid);
            void CreateProject(DtoProject dto);
            void UpdateProject(DtoProject dto);
            void DeleteProject(int id);
        }
    }

    using System.Collections.Generic;
    using System.Linq;
    using System.Transactions;
    using DAL.Models.DB;
    using Entities;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.Extensions.Options;
    
    namespace DAL
    {
        public class DaoProject :IDaoProject
        {
            private readonly IOptions<ConnectionStrings> _options;
            
            public DaoProject(IOptions<ConnectionStrings> options)
            {
                _options = options;
            }
    
            public DtoProject GetProjectById(int id)
            {
                var dto = new DtoProject();
    
                using (var context = new ProjectManagementContext(_options))
                {
                    var project = (context.Projects.Where(a => a.ProjectId == id)).SingleOrDefault();
    
                    if (project == null) return dto;
                    dto.ProjectId = project.ProjectId;
                    dto.ClientName = project.ClientName;
                    dto.ProjectName = project.ProjectName;
                    dto.Technology = project.Technology;
                    dto.ProjectType = project.ProjectType;
                    dto.UserId = project.UserId;
                    dto.StartDate = project.StartDate;
                    dto.EndDate = project.EndDate;
                    dto.Cost = project.Cost;
                }
    
                return dto;
            }
    
            public List<DtoProject> GetProjectsByUserId(string userid)
            {
                var dtos = new List<DtoProject>();
    
                using (var context = new ProjectManagementContext(_options))
                {
                    
                    dtos = (from a in context.Projects.Where(a => a.UserId.Contains(userid))
                        select new DtoProject
                        {
                            ProjectId = a.ProjectId,
                            ClientName = a.ClientName,
                            ProjectName = a.ProjectName,
                            Technology = a.Technology,
                            ProjectType = a.ProjectType,
                            UserId = a.UserId,
                            StartDate = a.StartDate,
                            EndDate = a.EndDate,
                            Cost = a.Cost
                        }).ToList();
                }
    
                return dtos;
            }
    
            public void CreateProject(DtoProject dto)
            {
                using (var context = new ProjectManagementContext(_options))
                {
                    var project = new Projects
                    {
                        ClientName = dto.ClientName,
                        ProjectName = dto.ProjectName,
                        Technology = dto.Technology,
                        ProjectType = dto.ProjectType,
                        UserId = dto.UserId,
                        StartDate = dto.StartDate,
                        EndDate = dto.EndDate,
                        Cost = dto.Cost
                    };
    
                    context.Projects.Add(project);
                    context.SaveChanges();
               }
            }
    
            public void UpdateProject(DtoProject dto)
            {
                var project = new Projects();
                
                using (var context = new ProjectManagementContext(_options))
                {
                   project = (context.Projects.Where(a => a.ProjectId == dto.ProjectId)).SingleOrDefault();
                }
    
                if (project != null)
                {
                    project.ClientName = dto.ClientName;
                    project.ProjectName = dto.ProjectName;
                    project.Technology = dto.Technology;
                    project.ProjectType = dto.ProjectType;
                    project.UserId = dto.UserId;
                    project.StartDate = dto.StartDate;
                    project.EndDate = dto.EndDate;
                    project.Cost = dto.Cost;
                }
    
                using (var dbcontext = new ProjectManagementContext(_options))
                {
                    if (project == null) return;
                    dbcontext.Entry(project).State = EntityState.Modified;
                    dbcontext.SaveChanges();
                }
            }
    
            public void DeleteProject(int id)
            {
                Projects project;
    
                using (var context = new ProjectManagementContext(_options))
                {
                   project = (context.Projects.Where(a => a.ProjectId == id)).SingleOrDefault();
                }
    
                if (project == null) return;
    
                using (var newContext = new ProjectManagementContext(_options))
                {
                   
                    var tasks = new DaoTask(_options).GetTasksByProjectId(project.ProjectId);
                    using (TransactionScope scope = new TransactionScope())
                    {
                        foreach (var task in tasks)
                        {
                            new DaoTask(_options).DeleteTask(task.TaskId);
                        }
    
                        newContext.Entry(project).State = EntityState.Deleted;
                        newContext.SaveChanges();
    
                        scope.Complete();
                    }
                }
            }
        }
    }

    using System;
    
    namespace Entities
    {
        public class DtoProject
        {
            public int ProjectId { get; set; }
            public string ClientName { get; set; }
            public string ProjectName { get; set; }
            public string Technology { get; set; }
            public string ProjectType { get; set; }
            public string UserId { get; set; }
            public DateTime StartDate { get; set; }
            public DateTime EndDate { get; set; }
            public decimal Cost { get; set; }
        }
    }


    • Edited by DA924x Monday, April 22, 2019 8:11 AM
    Monday, April 22, 2019 8:05 AM
  • Problem it is data layer separation. I think it is bad concept. First feeling can be "Ok we have data layer which is separated from others and we can use it wherever we want". It seems like reusable coding. But in second look, is not. Why not? 

    Because when you want to use data layer wherever you want, you create dependencies. Each method has contract with other side. If there are several other sides you need to have contract with each. Problem is when contract of one side is changed. There is dependency to another side and it start snowball (or butterfly) effect in project. You need update each method from other side. 

    There can be example GetProjecs() method. One place wants to have all project. Another place wants to have all project which are active. … You will create GetActiveProject … By this technique your data layer will have thousands and thousands method which can be used by everyone and everywhere. 

    Much bettern concept is create data layer by contract with domain or presentation layer. As first step is model domain (business) layer. When you will model it at first, you can start to use interfaces instead of concrete implementation of data layer. These interfaces are saved in domain layer. It means data layer project need reference to domain layer project. You will implement functionality which is needed in domain layer only. 

    This technique is known as dependency inversion. It means domain layer has not any dependency to another layer. But another layers have dependency to domain layer. It provides implement your domain layer clearly and implement only what you need in other layers. 

    When you don't have domain layer and your application is about show data from database (or another storage) there are some patterns to create presentation layer. You can do data layer is depend on presentation layer so you can create presentation model in data layer. To do this enables to you create domain layer later and implements second data layer for domain layer only. It means you have two data layers - for presentation layer which does CRUD operation only and for domain layer which can be more complex. 

    Wednesday, April 24, 2019 9:58 AM