Solved

Which is better please? Use LINQ directly, Or use it with List class passing a class of my products table?

Posted on 2015-01-08
9
114 Views
Last Modified: 2016-02-15
Hi
I had seen two videos about Linq to sql. Those two  videos has two approaches to bind data to GridView.
      Linq to sql approache:
o       where I select my data into var, then bind it to myGridview. See code below.
Linq-aspx-cs.JPG      List collection class approache:
o      Where I create a class " myProductObject".
o      I initiate an instance List of my class:
List<myProductObject> myList = new List<myProductObject>();
o      Then I fill in myList with my data using Linq.

myProductObject-cs.JPGLINQ-List--aspx-cs.JPG      Please tell me the deference between those two approaches? And which is better?
0
Comment
Question by:Mohammad Alsolaiman
  • 4
  • 2
  • 2
  • +1
9 Comments
 
LVL 52

Assisted Solution

by:Carl Tawn
Carl Tawn earned 100 total points
ID: 40538125
It depends on what you need to do.  Both of those snippets essentially do the same thing, the only difference being that the first example creates an anonymous type rather than the concrete class used in the second example.

If you need to be able to manually create, and manipulate, the custom objects from the database then you want the second approach.  If you are simply loading from a database and binding once, then the approach from the first example will suffice.
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
ID: 40538134
Functionally, there is no difference. I prefer the first approach because it's easier to read.
0
 

Author Comment

by:Mohammad Alsolaiman
ID: 40538261
Thanks to all of you for the reply "If you need to be able to manually create, and manipulate, the custom objects from the database then you want the second approach."
I like it, it sounds good to me.
Do you mean that I can do my manipulating using the properties and the functions inside the class?
If so, would you please guide me to good example of these  manipulations.
0
 
LVL 74

Assisted Solution

by:käµfm³d 👽
käµfm³d   👽 earned 100 total points
ID: 40538278
I should clarify my statement as I did not look closely enough at the code. I prefer the ToList call in the first example over the AddRange call in the second.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 32

Accepted Solution

by:
it_saige earned 300 total points
ID: 40538288
The first method uses a well defined type (the class), whereas the second uses an anonymous type.

What does this mean for you.  Well it really depends on how you want to interact with your object.  When using the first method, you can do a direct cast to the databounditem since it is well defined.  With the second, you have to get the cell values directly.  Consider the following:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace EE_Q28592993
{
	public partial class Form1 : Form
	{
		private List<DataObject> data = null;
		private bool isLoading = false;

		public Form1()
		{
			InitializeComponent();
			if (data == null)
				data = new List<DataObject>();

			isLoading = true;
			dataGridView1.RowHeadersVisible = false;
			dataGridView2.RowHeadersVisible = false;
			dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
			dataGridView2.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
			dataGridView1.RowEnter += OnRowEnter;
			dataGridView2.RowEnter += OnRowEnter;
		}

		private void OnLoad(object sender, EventArgs e)
		{
			for (int i = 0; i < 20; i++)
				data.Add(new DataObject() { ID = i, Name = string.Format("SomeName{0}", i), Created = DateTime.Now.AddDays(i) });

			dataGridView1.DataSource = (from row in data select row).ToList();
			dataGridView2.DataSource = (from row in data select new { row.ID, row.Name, row.Created }).ToList();
			isLoading = false;
		}

		private void OnRowEnter(object sender, DataGridViewCellEventArgs e)
		{
			if (!isLoading)
			{
				if (sender is DataGridView)
				{
					DataGridView dgv = sender as DataGridView;
					if (dgv == dataGridView1)
					{
						DataObject row = dgv.Rows[e.RowIndex].DataBoundItem as DataObject;
						MessageBox.Show(string.Format("ID: {0}; Name: {1}; Created: {2}", row.ID, row.Name, row.Created));
					}

					if (dgv == dataGridView2)
					{
						var rowObject = dgv.Rows[e.RowIndex].DataBoundItem;
						object[] row = new object[3];
						row[0] = dgv.Rows[e.RowIndex].Cells[0].Value;
						row[1] = dgv.Rows[e.RowIndex].Cells[1].Value;
						row[2] = dgv.Rows[e.RowIndex].Cells[2].Value;
						MessageBox.Show(string.Format("ID: {0}; Name: {1}; Created: {2}", row[0], row[1], row[2]));
					}
				}
			}
		}
	}

	class DataObject
	{
		public int ID { get; set; }
		public string Name { get; set; }
		public DateTime Created { get; set; }
	}
}

Open in new window

Produces the following output -Capture.JPGIf we place a breakpoint on the OnRowEnter event and select an item from the first datagrid:Capture.JPGWe see that the DataBoundItem *is* a DataObject class object.

However, selecting an item from the second datagrid:Capture.JPG We see that the DataBoundItem does contain the properties of a DataObject class object, but we cannot access them unless we cast it as a DataObject (which when you deal with anonymous types, you do not normally created a class definition for the anonymous contents).Capture.JPG
Now, that being said, there is a way to access the values of the anonymous type by their well defined names without doing a direct cast.  We could use reflection, or (if we are using .NET 4.0) we can use the dynamic type:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace EE_Q28592993
{
	public partial class Form1 : Form
	{
		private List<DataObject> data = null;
		private bool isLoading = false;

		public Form1()
		{
			InitializeComponent();
			if (data == null)
				data = new List<DataObject>();

			isLoading = true;
			dataGridView1.RowHeadersVisible = false;
			dataGridView2.RowHeadersVisible = false;
			dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
			dataGridView2.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
			dataGridView1.RowEnter += OnRowEnter;
			dataGridView2.RowEnter += OnRowEnter;
		}

		private void OnLoad(object sender, EventArgs e)
		{
			for (int i = 0; i < 20; i++)
				data.Add(new DataObject() { ID = i, Name = string.Format("SomeName{0}", i), Created = DateTime.Now.AddDays(i) });

			dataGridView1.DataSource = (from row in data select row).ToList();
			dataGridView2.DataSource = (from row in data select new { row.ID, row.Name, row.Created }).ToList();
		}

		private void OnRowEnter(object sender, DataGridViewCellEventArgs e)
		{
			if (!isLoading)
			{
				if (sender is DataGridView)
				{
					DataGridView dgv = sender as DataGridView;
					if (dgv == dataGridView1)
					{
						DataObject row = dgv.Rows[e.RowIndex].DataBoundItem as DataObject;
						MessageBox.Show(string.Format("ID: {0}; Name: {1}; Created: {2}", row.ID, row.Name, row.Created));
					}

					if (dgv == dataGridView2)
					{
						dynamic rowObject = dgv.Rows[e.RowIndex].DataBoundItem;
						MessageBox.Show(string.Format("ID: {0}; Name: {1}; Created: {2}", rowObject.ID, rowObject.Name, rowObject.Created));
					}
				}
			}
		}

		private void OnShown(object sender, EventArgs e)
		{
			isLoading = false;
		}
	}

	class DataObject
	{
		public int ID { get; set; }
		public string Name { get; set; }
		public DateTime Created { get; set; }
	}
}

Open in new window

Breakpoint the OnRowEnter and viola:Capture.JPGCapture.JPG
So the long and the short of it is this, for easier dataobject access, you would use the well-defined method.  The other method takes more work to get the values out of the object.  In Linq-to-Sql (normally), you are dealing with a well-defined method any way as your datacontext should contain classes that represent the datamodel.

-saige-
0
 

Author Comment

by:Mohammad Alsolaiman
ID: 40538295
kaufmed thanks for the clarification.
Do you mean that both of them are same(returns List collection class). But the first one is easer code!
0
 

Author Comment

by:Mohammad Alsolaiman
ID: 40538314
it_saige thanks for the example you've wrote.
I'll try to understand it (I never write windows form application before) I'll do my best to understand your example.
0
 
LVL 32

Expert Comment

by:it_saige
ID: 40538331
No problem.  It is a lot to digest, especially when asking a question that contains as many code variations as you have.  Dealing with your code variations (as Kaufmed pointed out with regards to AddRange() vs. ToList()); remember that the datasource of the datagrid (for all intents and purposes) *is* a collection and normally collections (by the broadest terms) *are* lists.  The ultimate question then becomes, how do I want to work with the databound object?

-saige-
0
 

Author Closing Comment

by:Mohammad Alsolaiman
ID: 40551171
thanks to all of you for the good Clarification
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

In order to hide the "ugly" records selectors (triangles) in the rowheaders, here are some suggestions. Microsoft doesn't have a direct method/property to do it. You can only hide the rowheader column. First solution, the easy way The first sol…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now