So, I'm writing a fairly complex C# application right now, that uses MySQL as the database system. I'm wondering, what would be the best way to use MySQL through the entire program? Creating static functions so you can use it everywhere? Refering to a SQLHandler class, which does all the communication?
Thanks!
I would abstract the data access functions inside an interface which could act as a data access layer. Then have an implementation working with MySQL. Then always pass the interface to other layers of your application that need to query the database. This way you get weak coupling between those layers and make unit testing in isolation of those layers possible.
Let's have an example. Suppose that you have a Product model:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
}
Now you could define a repository which will abstract the operations you need to perform with this model:
public interface IProductRepository
{
Product Get(int id);
}
and then you could have an implementation of this interface working with MySQL:
public class MySQLProductRepository: IProductRepository
{
private readonly string _connectionString;
public MySQLProductRepository(string connectionString)
{
_connectionString = connectionString;
}
public Product Get(int id)
{
using (var conn = new MySqlConnection(_connectionString))
using (var cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = "SELECT name FROM products WHERE id = #id";
cmd.Parameters.AddWithValue("#id", id);
using (var reader = cmd.ExecuteReader())
{
if (!reader.Read())
{
return null;
}
return new Product
{
Id = id,
Name = reader.GetString(reader.GetOrdinal("name"))
};
}
}
}
}
Now every layer of your application which needs to work wit products could simply take the IProductRepository as constructor parameter and call the various CRUD methods.
It is only inside the composition root of your application where you would wire the dependencies and specify that you would be working with a MySQLProductRepository. Ideally the instance of this repository should be a singleton.
You might also checkout popular ORMS such as NHibernate, Entity Framework, Dapper, ... to simplify the implementation of the various CRUD operations inside your repositories and perform the mapping to the domain models. But even if you decide to use an ORM framework it is still good practice to separate the concerns into different layers in your application. This is very important when designing complex applications if you want they to remain maintainable.
A good practice is to make a Singelton MySQLHandler if you want to keep 1 connection alive all the time.
using System;
public class MySQLHandler
{
private static MySQLHandler instance;
private MySQLHandler() {}
public static MySQLHandler Instance
{
get
{
if (instance == null)
{
instance = new MySQLHandler();
}
return instance;
}
}
}
If you dont care for the number of connections you can also make a static MySQLHelper class.
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 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.
I have been tasked with a project at work of writing a class to connect to multiple different databases such as Oracle, SQL Server, Spatialite etc and get and set data values and I was wondering which of the two in the title you would recommend for this.
I have created a class that utilises OLE functionality in order to make connections and set and retrieve data as I thought ADO was more of an SQL Server specific technology. Is this the case or can ADO.NET be used for a variety of data sources? I have researched it quite a lot and most places that I have seen recommend OLE for multiple possible data sources whereas they recommend ADO for SQL Server.
Thanks
I can't see how OLE is going to provide a magic bullet for unifying the DAL. You want to use the data access framework that best suits the data source and abstract the implementation away from the application.
My guess is that you're hoping that using OLE will allow some unification of syntax. But this is not the case. Once you attempt to do something like paging, each data source is going to have its own quirks and how you connect to the source is not going to help unify the syntax differences. For example, in the case of paging, SQLite usings SKIP, TAKE. Oracle uses ROWNUM. Sql Server uses TOP.
I would approach the problem by creating a DAL that abstracts the entity classes away from the data source. Then you can use the connection type that is most suitable for the data source. For example, suppose my application wants to retrieve "Products" from a data source. My application would only know about the ProductFactory interface, not the specifics of the data source type. For example,
string id = "0000001";
IProductFactory factory = FactoryManager.GetProductFactory();
Product p = factory.Get(id);
In the example below, I implement the Oracle data access tier for the Product interfaces using ODP.Net (the best data access components for an Oracle data source). Then the data access tier looks like this:
IProductFactory:
public interface IProductFactory: IEntityFactory
{
Product Get(string productId);
IList<Product> GetAll();
int GetAllCount();
}
Product:
public class Product : IEntity<Product>
{
public string ProductId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
#region IEntity<Product> Members
public Product MapData(System.Data.IDataReader reader)
{
return new Product
{
Name = reader["name"] as string,
Description = reader["description"] as string
};
}
#endregion
}
Oracle ProductFactory
public class ProductFactory : EntityFactory, IProductFactory
{
#region IProductFactory Members
public Product Get(string productId)
{
Product p = null;
using (OracleConnection conn = new OracleConnection(ConnectionString))
{
using (OracleCommand cmd = new OracleCommand())
{
cmd.CommandText = "select * from product where productId = :productId";
cmd.Parameters.Add("productId", productId);
using (IDataReader reader = cmd.ExecuteReader())
{
p = new Product();
p.MapData(reader);
}
}
}
return p;
}
public IList<Product> GetAll()
{
throw new NotImplementedException();
}
public int GetAllCount()
{
throw new NotImplementedException();
}
#endregion
}
ADO.NET can be used to connect to any database with an ODBC connection. We use ADO.NET for pretty much everything (PostgreSQL, Oracle, MySQL, SQL Server, etc), and it is the core database access method of most ORM products.
I'd recommend you to abstract away the DAL (data access layer) through an interface, and then create multiple DALs one for each type of database.
Your task can become a lot easier if you use a provider based ORM such as Entity Framework for your DALs private code.
For the public part all you have to do is implement the interface contract and you're fine.
I'm new to C# and ASP.NET MVC and i'm trying to understand the repository pattern. I've read a whole lot of articles, but I just don't understand how to use it. I'm currently using LINQ to SQL to access my SQL Server 2005 database and for testing purposes I created two tables. I have an Employees table and an EmployeeContacts table. The pk of both tables is UserName.
Employees
UserName
LastName
FirstName
Position
Email
Status
HireDate
EmployeeContacts
UserName
Contact1
Contact1Phone
Contact1Relationship
There is a one to one relationship between the two tables. An employee can be added, updated, and deleted and so can the data in the EmployeeContacts table.
So would I create a base repository to be used by both entities or should I create a repository for each entity separately? If anybody would be willing to show me some code that would be great.
So far, I have this Employee repository. I also have one for EmployeeContacts.
namespace MvcDirectoryLINQ.Models
{
public class EmployeeRepository
{
private TestDB_DataDataContext db = new TestDB_DataDataContext();
private UserName u = new UserName();
//
// Query Methods
public IQueryable<Employee> FindAllEmployees()
{
return db.Employees;
}
public IQueryable<Employee> FindRecentEmployees()
{
DateTime myDate = DateTime.Today.AddMonths(-6);
return from empl in db.Employees
where empl.HireDate >= myDate
orderby empl.HireDate
select empl;
}
public Employee GetEmployee(string UserName)
{
return db.Employees.SingleOrDefault(d => d.UserName == UserName);
}
//
// Insert/Delete Methods
public void Add(Employee employee)
{
// get the UserName which is created from the email
employee.UserName = u.ReturnUserName(employee.Email);
//Insert the new employee into the database
db.Employees.InsertOnSubmit(employee);
db.EmployeeContacts.InsertOnSubmit(employee.EmployeeContact);
}
public void Delete(Employee employee)
{
db.EmployeeContacts.DeleteOnSubmit(employee.EmployeeContact);
db.Employees.DeleteOnSubmit(employee);
}
//
// Persistence
public void Save()
{
db.SubmitChanges();
}
}
}
I have a class for an EmployeeFormViewModel:
namespace MvcDirectoryLINQ.Models
{
public class EmployeeFormViewModel
{
//Properties
public Employee Employee { get; private set; }
public EmployeeContact EmployeeContact { get; private set; }
//Constructor
public EmployeeFormViewModel(Employee employee, EmployeeContact employeeContact)
{
Employee = employee;
EmployeeContact = employeeContact;
}
}
}
Code for EmployeeController:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(string UserName, FormCollection formValues)
{
Employee employee = employeeRepository.GetEmployee(UserName);
EmployeeContact employeecontact = employeecontactRepository.GetContact(UserName);
try
{
UpdateModel(employee);
UpdateModel(employeecontact);
employeecontactRepository.Save();
employeeRepository.Save();
return RedirectToAction("Details", new { UserName = employee.UserName });
}
catch
{
foreach (var issue in employee.GetRuleViolations())
{
ModelState.AddModelError(issue.PropertyName, issue.ErrorMessage);
}
return View(new EmployeeFormViewModel(employee, attendingID));
}
}
In my View, i inherit from #model MvcDirectoryLINQ.Models.EmployeeFormViewModel. My Employee data saves correctly but the EmployeeContacts don't and I have no idea why.
Am I implementing the repository pattern correctly?
The main goal when using the Repository Pattern (as far as I understand it) is to decouple your application from using a specific Data Access Layer. You haven't done that here because you create I can see that your EmployeeRepository class does not implement an interface. You really want to have something like EmployeeRepository : IEmployeeRepository
Then, in your Controller code, you can pass around an IEmployeeRepository instead of working concretely with your EmployeeRepository. This will give you two benefits:
Should you ever need to switch the backend code, you only need to make another class that implements the interface.
When you go to test your Controllers, you can pass around a so called mock object that implements the interface instead of hitting the actual database, which slows your tests down and also breaks Unit Testing.
Another thing I noticed is that you spin up a DataContext inside your repository. If you wanted to make changes to multiple different types of objects you would therefore have multiple DataContexts open, which I don't think is what you want, since your changes won't be transactional. You may want to look into the Unit of Work Pattern for a solution.
When learning about a pattern, try to figure out the main benefit first before trying to implement it. In some cases it may not make sense. Please let me know if you would like me to elaborate on anything. Good luck.
So would I create a base repository to be used by both entities or should I create a repository for each entity separately?
The general rule when using the repository pattern is that there should be one repository class per each primary entity type. Can the EmployeeContacts live independently of any Employee? If so, they should have their own repository. Are them always related to an Employee? If so, manage them by using the Employee repository itself.
is this a common and/or good approach?
In my ViewModel(Wpf) or Presenter(WinForms) I do this:
ICustomerService customerService = MyService.GetService<ICustomerService>();
ICustomerList customerList = customerService.GetCustomers();
the CustomerService class looks like this:
public class CustomerService : ICustomerService
{
public ICustomerList GetCustomers()
{
return _customerDataProvider.GetCustomers();
}
}
public class CustomerDataProvider()
{
public ICustomerList GetCustomers()
{
// Open SQL connection,
// get back a SqlDataReader and iterate it
// in the loop write all data into a ICustomer object
// add the ICustomer object to the ICustomerList
// return ICustomerList object...
}
}
Retrieving data from a database is the plumbing of your application. And the less plumbing you have to write yourself, the more productive you will be.
I usually go to LINQ directly in the client:
sp_GetCustomersResult customers;
using (var db = new DbDataContext(ConnectionString))
customers = db.sp_GetCustomers();
This works fairly well, and lets me focus on adding customer value instead of database access layers.
I haven't found much value in declaring interfaces for business classes or for custom collections since extension methods became available. I would have GetCustomers return IEnumerable<Customer>.
If you plan on working extensively with business objects then you should look into using an object/relation mapper such as NHibernate. Or use LINQ2SQL or Entity Framework to reduce the amount of repetitive plumbing code you have to write.