Is this aproach the best that exist to databind a datagridview?
I\'ve seen many people with problems binding datagridviews and after a lot of work I found this as t
You could just bind the DataGridView
to the DataSource
with AutoGenerateColumns on something like
dataGridView1.DataSource = [yourDataSource]
Then loop through the columns and set their properties in the loop which would allow you to hide columns you don't want to see, name headers etc.
This is how I do mine
foreach (DataGridViewColumn col in dgvReconciledItems.Columns)
{
switch (col.Name)
{
case "Column1":
col.HeaderText = "Header1";
col.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
col.FillWeight = 30;
break;
case "Column2":
col.HeaderText = "Header2";
col.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
col.FillWeight = 10;
break;
default:
col.Visible = false;
break;
}
}
Any questions let me know
So, in order to explain my thoughts better I'll write an answer (as it doesn't restrict me with the character count) but I
want to make it clear that I only add my thoughts about how your initial code could be made better and not how it must be
done.
Having said that let's get into the topic. I'll start with Step 2) Create an object that represents a row in the datagridview.
because I think this is what it's all about. Your database model (the tables and the columns for each table) sometime will reflect
your business model, but sometimes in your business logic you'll need to use information from 2 or more database tables and I think
that the most common approach is the one you've chosen - create a new class that represents the business logic needs. Even here you
are given some options like using anonymous objects or [NotMapped]
properties but I'll leave these to someone that actually prefers
any of these other options since I also would go with a new class.
I'll skip step 3 and 4 since I don't think I have something of value to write about that and go straight to Step 5) query the database
.
The first thing that I think should be reconsider is the responsibilities that you give to each Model
, View
and Controller
. As I wrote
in one of my comments, in my opinion having another project dedicated to handle the data access is as far the best approach I've found. Why I
prefer this approach? Well - first, as I wrote, your database model will most probably not reflect your business model. Let say in your project you
have Model
folder and you put there all the entities plus the business objects. It's confusing, even with a fairly small application you will find
yourself with many classes and it will be difficult even for you at some point to tell which class represents a database tables (entity) and which you
use in your business logic. It will be even harder for the man after you to find out those things, or even you, after a few months later. So it's a simple
thing that can make your code much more readable which alone is not a small achievement. And after some more reading about how to decouple an application
if we decide that indeed a separate project for data access is a good approach, then it makes a lot of sense to put the logic for getting that data in this project.
The way I like to do that (keep in mind I don't have much experience, I'm learning as I'm writing this stuff) is to use Repository
pattern. You can read a lot
about this pattern and the different ways it's used, but just to show you the advantage of using repository instead of
My_DBModel DB_context = new My_DBModel();
List<myDatabaseObject> myDatabaseObject_list = DB_context.myDatabaseObject.ToList();
Let's say you have two entities - User
and Order
. And you have a GenericRepository
that implements the basic methods that you will use while manipulating data:
public class GenericRepository<TEntity> : IRepository<TEntity> where TEntity : class
{
internal MyDbContext context;
internal DbSet<TEntity> dbSet;
public GenericRepository(MyDbContext context)
{
this.context = context;
this.dbSet = context.Set<TEntity>();
}
public virtual IQueryable<TEntity> GetAll()
{
return dbSet;
}
public virtual IQueryable<TEntity> GetBy(Expression<Func<TEntity, bool>> predicate)
{
return dbSet.Where(predicate);
}
public virtual TEntity GetById(long id)
{
return dbSet.Find(id);
}
//And so on...
and you have also UserRepository
and OrderRepository
which both inherit from the GenericRepository
so already for each entity you have all basic methods
implemented so you don't have to repeat yourself every time when you want to perform Delete
or Update
.And why I don't like My_DBModel DB_context = new My_DBModel();
?
Well, imagine that you use some method, let's say GetOrdersBySomething()
and you use this method on several places in your code by querying the database. What will happen if
someone decides to write a stored procedure which will return this information from now on - you have to find all places where you actually use this method and change the logic.
Let's say that few months later you have to use data from a web service too.. each change force you to rewrite the same logic on different places in your application. But if you
use repository you will just have GetOrdersBySomething()
in your OrdersRepository
and each time when you have to make a change you gonna make it only here and nowhere else.
Also, if I understood your post correctly, the main topic is about being able to collect data from several tables in the database and bind it as a datasource. So what kind of problems this may cause. Even if you are dealing with relatively small amount of data, if you first query each table separately and then try to populate your business object on the server side this may cause a big performance issue. If you have to use let say 3 tables each with 10columns, that makes 30 columns total. If you need only 15 of them, then what you want is the database server to do it's work and return those columns in the way you need them, so the work on the server side is as little as possible. Which lead me to the next topic that I point out - the expression trees. I won't write much about them cause I don't think I have some deep understanding about them, but here is the official msdn page about the topic http://msdn.microsoft.com/en-us/library/bb882637.aspx where you can read more about what expression tree is, what is the idea behind it. And when you get the idea of what exactly expression tree is, then it will be more clear why I think that your example where you query against only one table is not the best one, because this approach really shines when you execute the appropriate query.