最好的方法来绑定一个DataGridView到数据库实体/ IES [英] Best approach to bind a datagridview to database entity/ies

查看:95
本文介绍了最好的方法来绑定一个DataGridView到数据库实体/ IES的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是形式给出了存在数据绑定一个DataGridView最好?

Is this aproach the best that exist to databind a datagridview?

我看到很多人的问题结合datagridviews和大量的工作,我发现这是最好的方法之后。我希望它能帮助其他人,有人可以添加一种进步。

I've seen many people with problems binding datagridviews and after a lot of work I found this as the best method. I hope it helps other people, and someone can add an improvement.

第1步)创建的dataGridView及其列与编辑。

第2步)创建重新presents排在DataGridView对象。

因为你需要这个对象可能有数据库实体的多个实例。下面是两个物体的例子(在DataGridView两列)

This object may have as many instances of database entities as you need. Here's an example with two objects (two columns in the datagridview)

public class ObjectToShow
{
    MyDatabaseObject myDatabaseObject = new MyDatabaseObject();

    public ObjectToShow(MyDatabaseObject myDatabaseObject)
    {
        this.myDatabaseObject = myDatabaseObject;
    }

    public string Data1 //to asign to a datagridview column
    {
        get { return myDatabaseObject.data1; }
        set { myDatabaseObject.data1 = value; NotifyPropertyChanged("Data1")}
    }

    public string Data2 //to asign to another datagridview column
    {
        get { return myDatabaseObject.data2; }
        set { myDatabaseObject.data2 = value; NotifyPropertyChanged("Data2"); }
    }

    //This is to notify the changes made to the object directly and not from the control. This refreshes the datagridview.
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

}

第3步)的形式创建ObjectToshow的的BindingList和BindingSource的如下

BindingList<ObjectToshow> ObjectToShow_list = new BindingList<ObjectToshow>();
BindingSource bindingSource = new BindingSource();

第4步)创建绑定这种方法

//if we don't put this, each public property in ObjectToshow will generate a new column in the datagridview
//I think it's best to create the columns from the editor.
dataGridView1.AutoGenerateColumns = false;

//database -> <- bindingList -> <- bindingSource -> <- datagridview <- user
bindingSource.DataSource = ObjectToShow_list;
dataGridView1.DataSource = bindingSource;

dataGridView1.Columns["Column_Data1"].DataPropertyName = "Data1";
dataGridView1.Columns["Column_Data2"].DataPropertyName = "Data2";

第5步)查询数据库

//Example bringing all the data from a database table. This should be done in a controller class.
My_DBModel DB_context = new My_DBModel();    
List<myDatabaseObject> myDatabaseObject_list = DB_context.myDatabaseObject.ToList();

//Clear de previous data    
ObjectToShow_list.Clear();

//Add the queried elements to the bindingList
foreach (myDatabaseObject item in myDatabaseObject_list)
{
    ObjectToshow objectToshow = new ObjectToshow(item);
    ObjectToShow_list.Add(objectToshow);
}

第六步),只要你想修改从的BindingList数据或datagridview的。然后DB_context.saveChanges()。

要添加数据,直接将它添加到DB_context.myDatabaseObject.Add(新...),再次查询数据库;如果你想从datagridview的,我认为你必须处理该事件,并把它添加到上下文反正添加它。

To add data, add it directly to DB_context.myDatabaseObject.Add(new ...) and query the database again; If you want to add it from the datagridview I think you have to handle the event and add it to the context anyway.

这是我做的,它的工作原理,但我不知道这是否是最好的方式。先谢谢了。

This is what I do and it works, but I'm not sure if it's the best way. Thanks in advance.

推荐答案

因此​​,为了解释我的想法更好,我会写一个答案(因为它不以字符数限制我),但我 想清楚地表明,我只加了我的想法如何您最初的code可以变得更好,而不是如何它必须是 完成。 说了这么多,让我们进入正题。我将开始与第2步)创建重新$ P $在DataGridView psents一排的对象。 因为我觉得这是它的全部。数据库模型(表和列用于每个表)的某个时候将反映 你的商业模式,但有时在你的业务逻辑,你需要从2个或多个数据库表使用的信息,我想 这是最常见的方法是你选择一个 - 创建重新presents业务逻辑需要一个新的类。即使在这里你 给出一些选项,比如使用匿名对象或 [NotMapped] 属性,但我会离开这些的人,其实prefers 任何一个其他的选择,因为我还要去一个新的类。 我会跳过步骤3和4,因为我不认为我有一些有价值的东西写了,直接进入步骤5)查询数据库。 我认为应该重新考虑的第一件事是,你给每个责任型号查看控制器。当我写了 在我的意见之一,有专门的处理数据访问的另一个项目我的意见是,据我已经找到了最好的方法。为什么我 preFER这种做法?好了 - 首先,因为我写的,你的数据库模型将很可能不能反映你的商业模式。让说,在你的项目,你 有型号文件夹,你把那里所有的实体以及业务对象。这是混乱的,甚至是一个相当小的应用程序,你会发现 自己与许多类,这将是困难的,即使你在某些时候,告诉哪个类重presents数据库中的表(实体),哪些是你 在业务逻辑中使用。它甚至会为男人更难之后你找出那些东西,甚至是你,以后几个月后。所以这是一个简单的 这可以让你的code更可读仅此一项事情是一个不小的成就。而之后如何去耦应用一些更多的阅读 如果我们决定确实的数据访问一个单独的项目是一个很好的方法,那么它使一个很大的意义把逻辑获取的数据在这个项目。 我喜欢做的(记住,我没有太多的经验,我学习,我在写这东西)的方法是使用模式。你可以读了很多 这个模式和不同的方式使用它,但只是为了告诉你使用存储库来代替的优势

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();

让我们假设你有两个实体 - 用户订单。而你有一个 GenericRepository 实现您将使用在操纵数据的基本方法:

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...

和你有同样 UserRepository OrderRepository 这无论是从继承 GenericRepository 所以已经为每个实体您拥有所有基本方法         实现这样你就不必每次都重复自己,当你想执行删除更新。而我为什么不喜欢 My_DBModel DB_context =新My_DBModel(); ?         好吧,假设你使用一些方法,比方说 GetOrdersBySomething()键,您可以通过查询数据库的几个地方在code使用此方法。如果会发生什么         有人决定写一个存储过程,它会从现在开始,返回此信息 - 你必须找到你居然用这种方法,改变逻辑的所有地方。         比方说,几个月后,你必须使用数据从Web服务太..每次改变迫使你重写同样的逻辑在你的应用程序不同的地方。但是,如果你         使用存储库,你就只能 GetOrdersBySomething() OrdersRepository ,每一次当你必须做出改变,你会使只有在这里,别的地方。

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.

另外,如果我理解正确的您的文章,主要的话题是关于能够从数据库中的几个表收集数据,并将其绑定为一个数据源。那么什么样的问题         这可能会导致。即使你正在处理的数据量相对较少的,如果你先查询每个单独的表,然后尝试填充您的业务对象在服务器端本         可能会造成大的性能问题。如果你必须使用让说每3个表与10columns,这使得30列总计。如果你只需要15人,那么你想要的是数据库服务器         做到这一点的工作,并返回这些列在你需要他们的方式,所以在服务器端的工作是尽可能少。这使我的下一个话题,我想指出 - 前pression树。我不会         写很多关于他们的,因为我不认为我对他们有一些深层次的理解,但这里的话题的 http://msdn.microsoft.com/en-us/library/bb882637.aspx ,你         可以阅读更多关于EX pression树,什么是它背后的理念。当你得到的究竟是什么前pression树的想法,那么这将是更清楚,为什么我觉得你的例子,         您查询只针对一个表是不是最好的,因为这种方式当你执行相应的查询,真正的亮点。

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.

这篇关于最好的方法来绑定一个DataGridView到数据库实体/ IES的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆