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.
Related
I'm learning C# & ASP.NET.
I'm trying to make a struct, I don't know is it ok call it ORM.
I have a database (using Entity Framework), and I try to separate SQL queries from aspx's codebehinds.
I've got 4 tables in my database (Kitaplar,Musteriler,Kiralamalar,Turler)
in my Kitaplar table I have got 8 field (KitapID(FK),KitapAdi,ISBN,Yayinevi,Yazaradi,Basimtarihi,Stok,TurTurID).
I created a class Kitapmodel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace KütüphaneYonetimSistemi.Models
{
public class KitapModel
{
public int KitapID { get; set; }
public string KitapAdı { get; set; }
public string ISBN { get; set; }
public string Yayınevi { get; set; }
public string YazarAdı { get; set; }
public DateTime BasimTarihi { get; set; }
public int Stok { get; set; }
public int TurTurID { get; set; }
}
}
I also created kitapModelProvider.cs for database connection and other things At this is the point I'm stuck.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace KütüphaneYonetimSistemi.Providers
{
public class kitapModelProvider
{
}
public KitapModel getByKitapID(int ID)
{
KutuphaneYonetimDB db = new KutuphaneYonetimDB();
KitapModel bookListEF = from k in db.Kitaplar
join t in db.Turler
on k.TurTurID equals t.TurID
select new
{
k.KitapAdı,
k.YazarAdı,
t.TurAdı,
k.Yayınevi,
BasimTarihi = k.BasimTarihi.ToString().Replace(" 12:00AM", "").Replace("Jan", "Ocak").Replace("Feb", "Şubat").Replace("Mar", "Mart").Replace("Jun", "Haziran").Replace("Sep", "Eylül").Replace("Nov", "Kasım").Replace("Oct", "Aralık").Replace("Apr","Nisan"),
k.ISBN,
k.Stok
};
return bookListEF;
}
public void insertKitap(KitapModel kitap)
{
KutuphaneYonetimDB db = new KutuphaneYonetimDB();
db.Kitaplar.Add(kitap);
db.SaveChanges();
}
/*
other methods
*/
}
And in my createBook.aspx.cs file I want to do something like this;
KitapModel kitap = new Kitapmodel {
kitapAdi = "Harry Potter ve Felsefe Taşı",
ISBN = ......
Yayınevi....
...
Stok = 5,
TurTurID = 1 }
kitapModelProvider.insertKitap(kitap) // or kitapModel.insertKitap
Okay since you are new to programming on ASP.NET, I try to put you on a right path.
First What is an ORM :
From wikipedia:
Object-relational mapping (ORM, O/RM,
and O/R mapping) in computer software
is a programming technique for
converting data between incompatible
type systems in relational databases
and object-oriented programming
languages. This creates, in effect, a
"virtual object database" that can be
used from within the programming
language. There are both free and
commercial packages available that
perform object-relational mapping,
although some programmers opt to
create their own ORM tools.
It's good for abstracting the data-store (SQL Databases / NoSQL Databases and so on) out in order to provide an interface that can be used in your code. Commonly used ORMs within .NET for Connecting to SQL are:
ADO.NET
LINQ To SQL
ADO.NET Entity Framework
Now You've choosen EF (Entity Framework) as Object-relational mapping [ORM]. Second Step would be learning basics of EF Which you can Find here.
EF Provides 2 type of approaches:
Code-First
Where you would provide the POCO classes and their mapping And EF would create the table designs for you within the dbcontext class's OnBuildingMethod().
Database-First
Traditional way to create table designs then you connect your database to your application and add a ADO.NET Entity Data Model and using it's wizard you call all of your tables and create their POCOs for you.
After You've learned About these and how it does work, you need to know about The EF CRUD Operations.
And in the end you can start look at Repository Pattern And Unit of Work Pattern using EF.
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.
My application has be entity model as below and use Dapper
public class Goal
{
public string Text { get; set; }
public List<SubGoal> SubGoals { get; set; }
}
public class SubGoal
{
public string Text { get; set; }
public List<Practise> Practices { get; set; }
public List<Measure> Measures { get; set; }
}
and has a repository as below
public interface IGoalPlannerRepository
{
IEnumerable<Goal> FindAll();
Goal Get(int id);
void Save(Goal goal);
}
I came across two scenarios as below
While retrieving data (goal entity), it needs to retrieve all the related objects in hierarchy (all subgoals along with practices and measures)
When a goal is saved all the related data need to be inserted and/or updated
Please suggest is there a better way to handle these scenarios other than "looping through" the collections and writing lots and lots of SQL queries.
The best way to do large batch data updates in SQL using Dapper is with compound queries.
You can retrieve all your objects in one query as a multiple resultset, like this:
CREATE PROCEDURE get_GoalAndAllChildObjects
#goal_id int
AS
SELECT * FROM goal WHERE goal_id = #goal_id
SELECT * FROM subgoals WHERE goal_id = #goal_id
Then, you write a dapper function that retrieves the objects like this:
using (var multi = connection.QueryMultiple("get_GoalAndAllChildObjects", new {goal_id=m_goal_id})) {
var goal = multi.Read<Goal>();
var subgoals = multi.Read<SubGoal>();
}
Next comes updating large data in batches. You do that through table parameter inserts (I wrote an article on this here: http://www.altdevblogaday.com/2012/05/16/sql-server-high-performance-inserts/ ). Basically, you create one table for each type of data you are going to insert, then write a procedure that takes those tables as parameters and write them to the database.
This is super high performance and about as optimized as you can get, plus the code isn't too complex.
However, I need to ask: is there any point to keeping "subgoals" and all the other objects relational? One easy alternative is to create an XML or JSON document that contains your goal and all its child objects serialized into text, and just save that object to the file system. It's unbelievably high performance, very simple, very extensible, and takes very little code. The only downside is that you can't write a SQL statement to browse across all subgoals with a bit of work. Consider it - it might be worth a thought ;)
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.