I know this question is asked many times, but I couldnt get a clear picture of what I need.
I have a WPF application which I need to redo using 3- Tier approach.
I have used Entity Framework for creating datamodel and using Linq queries for querying the data.
objCustomer = dbContext.Customers.Where(c => c.CustCode == oLoadDtl.CustNo).First();
I use Linq queries where ever I need in the program to get records from the database.
So, I just would like to know which all stuff comes under DAL, Business logic and UI layers.
Also, how do I separate them?
Can the entity datamodel considered as a DAL?
Is it a better idea to put the entity model in a separate class library?
It's better to create special class called DataAccess to encapsulate EntityFramework-invokes. For business logic you can create model classes, they will use DAL if needed. Other details depend on what your application should do.
For example:
//DAL
public class DataAccess
{
public static void GetCustomerByNumber(int number)
{
var objCustomer = dbContext.Customers.Where(c => c.CustCode == number).First();
return objCustomer;
}
}
//Models
public class Customer
{
public string Name { get; set; }
public int Number { get; set; }
public Customer GetCustomerByNumber(int number)
{
return DataAccess.GetCustomerByNumber(number);
}
public void ChangeProfile(ProfileInfo profile)
{
//...
}
}
Main things are extensibility, re-usability and efficiency of your solutions.
Related
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?
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:
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"?
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
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
I've got problems with joining DDD and EF Core.
I'm making project using DDD architecture. As Data Access level I use generic Unit of Work pattern taken from here.
public interface IUnitOfWork
{
IRepository<TDomain> Repository<TDomain>() where TDomain : class;
}
public interface IRepository<TDomain>
{
TDomain Get(Expression<Func<TDomain, bool>> predicate);
}
Realizing these interfaces I use EF Core.
I've got some domain model with 2 classes
public class MainClass
{
public int Id { get; set; }
public List<RelatedItem> Items { get; set; }
}
public class RelatedItem
{
public int Id { get; set; }
public MainClass Parent { get; set; }
public DateTime Date { get; set; }
public string SomeProperty { get; set; }
}
In real life of my project MainClass has collection with hundreds of RelatedItems. In order to perform some operations I need only one RelatedItem per request with some date. It can be done by searching through Items property.
Incapsulating perfomance of EF Core in unit of work I have to load explicitly entities from DB with related items, because business login layer doesn't know anything about realization of UnitOfWork's repository. But this operation is very slow.
So I decided to create MainClassService which injects in costructor unitOfWork and have method which returns only one RelatedItem, and it works fine.
public class MainClassService
{
IUnitOfWork unitOfWork;
public MainClassService(IUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork ?? throw new ArgumentNullException();
}
public RelatedItem GetRelatedItemByDate(int mainClassId, DateTime date)
{
return unitOfWork.Repository<RelatedItem>().Get(c => c.Parent.Id == mainClassId && c.Date == date);
}
}
So I've got situation when I cannot use property Items directly because of EF Core, but I should use them because of DDD architecture.
And my question is: is it ok to use such a construction?
From what it seems from your question, the MainClass is an Aggregate root and RelatedItem is a nested entity. This design decision should be based on the business rules/invariants that must be protected. When an Aggregate needs to mutate, it must be fully loaded from the repository, that is, the Aggregate root and all its nested entities and value object must be in memory before it execute the mutating command, no matter how big it is.
Also, it is not a good practice to inject infrastructure services into Aggregates (or in nested entities). If you need to do this, then you must think again on your architecture.
So, from what I wrote you can see that the problem manifest itself only when you try to mutate the Aggregate. If you only need to read it or find it, you could create some dedicated services that find the data using infrastructure components. Your MainClassService seems to be such a case, where you need only to read/find some RelatedItem entities.
In order to be clear that the purpose is only reading, the MainClassService needs to return a readonly representation of the RelatedItem entities.
So, you just madee some first steps towards CQRS, where the models are split into two: READ model and WRITE model.
We are developing an application with the following layers:
UI
Business Layer (BL)
Data Layer (DL): Contains generic CRUD queries and custom queries
Physical Data Layer (PDL): e.g. Entity Framework
We are looking for a way to share the entities of the physical data layer to the DL and the BL.
These points are important in deciding the best architecure:
Reusability: the database fields should be migrated to the other layers as easy as possible
Fast implementation: adding a field to the database should not result in mapping entities between all layers
Extensibility: a BL entity can be extended with properties specific to the BL (likewise for a DL entity)
I've come across architectures that share entities for all layers (+ fast implementation, - extensibility) or architectures with an entity (DTO) per layer (+ extensibility, - fast implementation/reusability).
This blogpost describes these two architectures.
Is there an approach that combines these architectures and takes our requirements into account?
For now we've come up with the following classes and interfaces:
Interfaces:
// Contains properties shared for all entities
public interface I_DL
{
bool Active { get; set; }
}
// Contains properties specific for a customer
public interface I_DL_Customer : I_DL
{
string Name { get; set; }
}
PDL
// Generated by EF or mocking object
public partial class Customer
{
public bool Active { get; set; }
public string Name { get; set; }
}
DL
// Extend the generated entity with custom behaviour
public partial class Customer : I_DL_Customer
{
}
BL
// Store a reference to the DL entity and define the properties shared for all entities
public abstract class BL_Entity<T> where T : I_DL
{
private T _entity;
public BL_Entity(T entity)
{
_entity = entity;
}
protected T entity
{
get { return _entity; }
set { _entity = value; }
}
public bool Active
{
get
{
return entity.Active;
}
set
{
entity.Active = value;
}
}
}
// The BL customer maps directly to the DL customer
public class BL_Customer : BL_Entity<I_DL_Customer>
{
public BL_Customer (I_DL_Customer o) : base(o) { }
public string Name
{
get
{
return entity.Name;
}
set
{
entity.Name = value;
}
}
}
The DTO-per-layer design is the most flexible and modular. Hence, it is also the most reusable: don't confuse the convenience of reusing the same entities with the reusability of the different modules which is the main concern at the architectural level. However, as you pointed out, this approach is neither the fastest to develop nor the most agile if your entities change often.
If you want to share entities among the layers I wouldn't go through the hassle of specifying a hierarchy through the different layers; I'd either let all layers use the EF entities directly, or define those entities in a different assembly shared by all the layers -- the physical data layer included, which may directly persist those entities through EF code-first, or translate to/from those shared entities to the EF ones.
I'm a junior web developer trying to learn more every day.
What it the best practice for you guys to performe MVC repository pattern with Linq?
The one I use:
Create extra clases with the exact name of my .tt files with CRUD method like getAll(), getOne(), Update(), Delete() filling my own class with the entity framework and returning this, or using the entity framework crude
this is an example of what I'm actually doing.
this is my getAll method of my class for example User
public class CEmployee : CResult
{
public string name{get;set;}
public string lastname{get;set;}
public string address{get;set;}
//Extracode
public string Fullname // this code is not in the .tt or database
{
get
{
return name + lastname;
}
}
public <List>CEmployee getAll()
{
try
{
var result = (from n in db.Employee
select new CEmployee // this is my own class I fill it using the entity
{
name = n.name,
lastname = n.lastname,
address = n.address
}).ToList();
if (result.Count > 0)
{
return result;
}
else
{
return new List<CResult>
{
new CResult
{
has_Error = true,
msg_Error = "Element not found!!!!"
}
}
}
}
catch
{
return Exception();
}
}
}
that the way I do all thing I return a filled of my type, but on the web I see that people return the entity type normaly, But I do this to manipulate my response, And if I want to return extra information I just have to neste a list for example, whats the best way guys, return mytype or return the entity type ?
PD, I also use this class like my ViewModel.And I do this for all my classes.
One of the projects I am currently one uses Dependency Injection to setup the DAL (Data Access Layer.) We also are using an n-Tier approach; this separates the concern of the repository from the Business Logic and Front End.
So we would start with 4 or so base projects in the application that link to each other. One of that handles the Data Access, this would be your repository; read up on Ninject for more info on this. Our next tier is our Domain which houses the Entities built by the t4 template(.tt files) and also our DTO's (data transfer objects which are flat objects for moving data between layers.) Then we have a service layer, the service layer or business logic layer holds service objects that handle CRUD operations and any data manipulation needed. Lastly we have our front end which is the Model-View-ViewModel layer and handles the controllers and page building.
The MVVM calls the services, the service objects call the data access layer and Entity Framework works with Ninject to access the data and its stored in the DTO's as it is moved across layers.
Now this may seem overly complex depending on the application you are writing, this is built for a highly scalable and expandable web application.
I would highly recommend going with a generic repository implementation. The layers between your repository and the controller vary depending on a number of factors (which is kind of a broader/bigger topic) but the generic repository gets you going on a good implementation that is lightweight. Check out this article for a good description of the approach:
http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
Ideally in a MVC application, you will want to repositories in a different layer like in a separate project, let's call it Data layer.
You will have an IRepository interface that contain generic method signatures like GetAll, GetById, Create or UpdateById. You will also have abstract RepositoryBase class that contain shared implementation such as Add, Update, Delete, GetById, etc.
The reason that you use an IRepository Interface is, there are contracts for which your inherited repository class, such as EmployeeRepository in your case, need to provide concrete implementations. The abstract class serves as a common place for your shared implementation (and override them as you need to).
So in your case, what you are doing using LINQ with your DbContext is basically correct, but implementation like your GetAll method should be part of the generic/shared implementation in your abstract class RepositoryBase:
public abstract class RepositoryBase<T> where T : class
{
private YourEntities dataContext;
private readonly IDbSet<T> dbset;
protected RepositoryBase(IDatabaseFactory databaseFactory)
{
DatabaseFactory = databaseFactory;
dbset = DataContext.Set<T>();
}
protected IDatabaseFactory DatabaseFactory
{
get;
private set;
}
protected YourEntities DataContext
{
get { return dataContext ?? (dataContext = DatabaseFactory.Get()); }
}
public virtual T GetById(long id)
{
return dbset.Find(id);
}
public virtual T GetById(string id)
{
return dbset.Find(id);
}
public virtual IEnumerable<T> GetAll()
{
return dbset.ToList();
}
}
I would suggest you need to think about whether or not to return an error result object like CResult, and think about if your CEmployee and CResult should exist in this parent-child relationship. Also think about what you want to do with your CResult Class. It seems to me your CEmployee handles too many tasks in this case.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Let's say we have a project that will handle lots of data (employees, schedules, calendars....and lots more). Client is Windows App, Server side is WCF. Database is MS SQL Server. I am confused regarding which approach to use. I read few articles and blogs they all seem nice but I am confused. I don't want to start with one approach and then regret not choosing the other. The project will have around 30-35 different object types. A lot of Data retrieving to populate different reports...etc
Approach 1:
// classes that hold data
public class Employee
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
.....
}
public class Assignment
{
public int Id { get; set; }
public int UserId { get; set; }
public DateTime Date { get; set; }
.....
}
.....
Then Helper classes to deal with data saving and retrieving:
public static class Employees
{
public static int Save(Employee emp)
{
// save the employee
}
public static Employee Get(int empId)
{
// return the ugly employee
}
.....
}
public static class Assignments
{
public static int Save(Assignment ass)
{
// save the Assignment
}
.....
}
FYI, The object classes like Employees and Assignment will be in a separate Assembly to be shared between Sever and Client.
Anyway, with this approach I will have a cleaner objects. The Helper classes will do most of the job.
Approach 2:
// classes that hold data and methods for saving and retrieving
public class Employee
{
// constructors
public Employee()
{
// Construct a new Employee
}
public Employee(int Id)
{
// Construct a new Employee and fills the data from db
}
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
.....
public int Save()
{
// save the Employee
}
.....
}
public class Assignment
{
// constructors
public Assignment()
{
// Construct a new assignment
}
public Assignment(int Id)
{
// Construct a new assignment and fills the data from db
}
public int Id { get; set; }
public int UserId { get; set; }
public DateTime Date { get; set; }
.....
public int Save()
{
// save the Assignment
}
.....
}
.....
With this approach, Each object will do its own job.. Data still can be transferred from WCF to client easily since WCF will only share properties.
Approach 3:
Using Entity Framework.. beside the fact that I never worked with it (which is nice since I have to learn something new) I will need to create POCOs to transfer data between client and WCF..
Now, Which is better? more options?
Having peristence logic in object itself is always a bad idea.
I would use first aproach. It looks like Repository pattern. This way, you can easily debug peristing of data, because it will be clearly separated from rest of the logic of the object.
I would suggest using Entity Framework + Repository pattern. This way your entities are simple objects without any logic in them. All retrieve-save logic stays in repository. I have some successful experience with using generic repository, which is typed with entity, something similar is described here (generic repository part of the article). This way you write repository code only once and you can reuse it for all entities you have. E.g.:
interface IRepositry<T>
{
T GetById(long id);
bool Save(T entity);
}
public class Repository<T> : IRepository<T> {...}
var repository = new Repository<MyEntity>();
var myEntity = repository.GetById(1);
var repository2 = new Repository<MySecondEntity>();
var mySecondEntity = repository.GetById(1);
Whenever an entity needs some very specific operation, you can add this operation to a concrete typed implementation of IRepository:
interface IMySuperRepositry : IRepository<MySuperEntity>
{
MySuperEntity GetBySuperProperty(SuperProperty superProperty);
}
public class MySuperEntityRepository : Repository, IMySuperRepository
{...}
To create repositories it is nice to use a factory, which is based for example on configuration file. This way you can switch implementation of repositories, e.g. for unit testing, when you do not want to use repository that really accesses DB:
public class RepositoryFactory
{
IRepository<T> GetRepository<T>()
{
if (config == production)
return new Repository<T>(); // this is implemented with DB access through EF
if (config == test)
return new TestRepository<T>(); // this is implemented with test values without DB access
}
}
}
}
You can add validation rules for saving and further elaborate on this. EF also lets you add some simple methods or properties to generated entities, because all of them are partial classes.
Furthermore using POCOs or STEs (see later) it is possible to have EDMX DB model in one project, and all your entities in another project and thus distribute this DLL to client (which will contain ONLY your entities). As I understood, that's what you also want to achieve.
Also seriously consider using Self tracking entities (and not just POCOs). In my opinion they are great for usage with WCF. When you get an entity from DB and pass it to the client, client changes it and gives it back, you need to know, if entity was changed and what was changed. STEs handle all this work for you and are designed specifically for WCF. You get entity from client, say ApplyChanges and Save, that's it.
What about implementing the Save as an extension method? That way your classes are clean as in the first option, but the methods can be called on the object as in the second option.
public static class Employee
{
public static int Save(this Employee emp)
{
// save the employee
}
public static Employee Get(int empId)
{
// return the ugly employee
}
}
you're over thinking this. trying to apply technologies and patterns "just because" or "that's what they say" only makes the solution complicated. The key is designing the application so that it can easily adapt to change. that's probably an ambiguous answer, but it's what it all comes down to. how much effort is required to maintain and/or modify the code base.
currently it sounds like the patterns and practices are the end result, instead of a means to an end.
Entity Framework is a great tool but is not necessarily the best choice in all cases. It will depend on how much you expect to read/write from the database vs how much you expect to read/write to your WCF services. Perhaps someone better-versed in the wonderful world of EF will be able to help you. To speak from experience, I have used LINQ-TO-SQL in an application that features WCF service endpoints and had no issues (and in fact came to LOVE Linq-To-Sql as an ORM).
Having that said, if you decide that EF is not the right choice for you, it looks like you're on the right track with Approach 1. However, I would recommend implementing a Data Access Layer. That is, implement a Persist method in your business classes that then calls methods in a separate DAO (Data Access Object, or a class used to persist data from a business object) to actually save it to your database.
A sample implementation might look like this:
public class Employee
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public void Persist()
{
EmployeeDAO.Persist(this);
}
}
public class Assignment
{
public int Id { get; set; }
public int UserId { get; set; }
public DateTime Date { get; set; }
public void Persist()
{
AssignmentDAO.Persist(this);
}
}
public static class EmployeeDAO
{
public static int Persist(Employee emp)
{
// insert if new, else update
}
public static Employee Get(int empId)
{
// return the ugly employee
}
.....
}
public static class AssignmentDAO
{
public static int Persist(Assignment ass)
{
// insert if new, else update
}
.....
}
The benefit to a pattern like this is that you get to keep your business classes clean, your data-access logic separate, while still giving the objects the easy syntax of being able to write new Employee(...).Persist(); in your code.
If you really want to go nuts, you could even consider implementing interfaces on your Persistable classes, and have your DAO(s) accept those IPersistable instances as arguments.