0

I'm learning Entity Framework, I was a bit confused between BLL and DAL, according to my search, I found that Entity Framework is DAL.

There are two ways to create BLL and DAL below:

First approach: write a separate DAO for each object (including add, remove, findAll, ...). In the BLL will call the DAO to get the data or modify the necessary data.

I have StudentManagement which inherits from DbContext and placed in the DAL.

public partial class StudentManagement : DbContext
{
       public StudentManagement()
            : base("name=StudentManagement")
       {
       }

       public virtual DbSet<LOP> LOP { get; set; }
       public virtual DbSet<STUDENT> STUDENT { get; set; }

       protected override void OnModelCreating(DbModelBuilder modelBuilder)
       {
           modelBuilder.Entity<LOP>()
                       .HasMany(e => e.STUDENT)
                       .WithOptional(e => e.LOP)
                       .HasForeignKey(e => e.CLASS_ID);
       }
}

StudentDAO: query and modifying data if necessary.

class StudentDAO
{
    public StudentManagement context { get; set; }

    public StudentDAO()
    {
        context = new StudentManagement();
    }

    public IQueryable<STUDENT> findAll()
    {
        return context.STUDENT;
    }

    public void add(STUDENT student)
    {
        context.STUDENT.Add(student);
        context.SaveChanges();
    }

    public void remove(int id)
    {
        STUDENT student = context.STUDENT.Find(id);

        if (student != null)
        {
            context.STUDENT.Remove(student);
            context.SaveChanges();
        }    
    }
}

Student_BLL: call the StudentDAO to handle business and then return data to view.

class StudentBLL
{
    public List<STUDENT> getStudentInClass(int ClassID)
    {
        return new StudentDAO().findAll().Where(student => student.CLASS_ID == ClassID).ToList();
    }

    public List<STUDENT> findAll()
    {
        return new StudentDAO().findAll().ToList();
    }

    public STUDENT find(int id)
    {
        return new StudentDAO().findAll().FirstOrDefault(student => student.ID == id);
    }

    public void add(STUDENT student)
    {
        new StudentDAO().add(student);
    }

    public void remove(int id)
    {
        new StudentDAO().remove(id);
    }
}

Another approach: I don't have to create DAO for each object but use context in BLL and query directly using LINQ.

class LopSH_BLL
{
    public StudentManagement context { get; set; }

    public LopSH_BLL()
    {
        context = new StudentManagement();
    }

    public List<LOP> findAll()
    {
        return context.LOP.ToList();
    }

    public LOP find(int id)
    {
        return context.LOP.Find(id);
    }

    public void add(LOP lop)
    {
        context.LOP.Add(lop);
        context.SaveChanges();
    }

    public void remove(int id)
    {
        LOP lop = context.LOP.Find(id);
        context.LOP.Remove(lop);
        context.SaveChanges();
    }
}

Which is better and does it follow the rules of 3 layers?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Lê Rôn
  • 29
  • 4

1 Answers1

1

Although there is nothing wrong with the way you are accessing data, there are better approaches available as best practices. However, you should always consider the type of project before planning any specific software architecture.

Ask yourself a few questions:

  • Is this project going to grow over time, or it's just a simple project to apply some simple logic?
  • How many developers are going to work on the project?

I believe these two simple questions can guide you much more accessible to deciding the architecture of your project.

Now regarding your question:

Which is better, and does it follow the rules of 3 layers?

Nothing wrong with the way you are accessing data, but:

  1. Program to the interfaces.

Using interfaces is a crucial factor in making your code easily testable and removing unnecessary couplings between your classes. Check this post : What does it mean to "program to an interface"?

  1. Dependency Inversion & Dependency Injection

Understanding the meaning of these two and knowing the differences can help you so much down the road.

Check this post: Difference between dependency injection and dependency inversion

  1. Repository Pattern

The Repository Design Pattern in C# (or any OOP-supported language) mediates between the domain and the data mapping layers using a collection-like interface for accessing the domain objects. In other words, we can say that a repository design pattern acts as a "middle layer" between the rest of the application and the data access logic.

I believe this is an excellent example to check and learn: The Repository Pattern Example in C#

Last but not least, there are some well-proven architecture patterns in general which are good to know if you are serious in this journey:

  • Domain Driven Design (DDD)
  • Microservices Architecture Pattern
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Reza Heidari
  • 1,192
  • 2
  • 18
  • 23
  • 1
    Some programmer might argue that Entity Framework *already* implements a repository and unit-of-work pattern - the `DbSet` is the repository, the `DbContext` the unit of work. – marc_s May 22 '22 at 09:53
  • I didn't know that; thanks for mentioning it. By the way, excluding `The Repository Pattern Example in C#`, which I referenced as an example in the answer, I intended to target any ORM and not just EntityFramework. – Reza Heidari May 22 '22 at 11:11