Using Entity Framework & ADO.Net Data in C# 7

A look at various ways of accessing data within C# 7 applications, from the traditional ADO.Net models to Entity Framework and LINQ.

1,491 words, estimated reading time 5 minutes.
Introduction to Programming with C#

This article is part of a series of articles. Please use the links below to navigate between the articles.

  1. Learn to Program in C# - Full Introduction to Programming Course
  2. Introdution to Programming - C# Programming Fundamentals
  3. Introduction to Object Oriented Programming for Beginners
  4. Introduction to C# Object-Oriented Programming Part 2
  5. Application Flow Control and Control Structures in C#
  6. Guide to C# Data Types, Variables and Object Casting
  7. C# Collection Types (Array,List,Dictionary,HashTable and More)
  8. C# Operators: Arithmetic, Comparison, Logical and more
  9. Using Entity Framework & ADO.Net Data in C# 7
  10. What is LINQ? The .NET Language Integrated Query
  11. Error and Exception Handling in C#
  12. Advanced C# Programming Topics
  13. All About Reflection in C# To Read Metadata and Find Assemblies
  14. What Are ASP.Net WebForms
  15. Introduction to ASP.Net MVC Web Applications and C#
  16. Windows Application Development Using .Net and Windows Forms
  17. Assemblies and the Global Assembly Cache in C#
  18. Working with Resources Files, Culture & Regions in .Net
  19. The Ultimate Guide to Regular Expressions: Everything You Need to Know
  20. Introduction to XML and XmlDocument with C#
  21. Complete Guide to File Handling in C# - Reading and Writing Files

Active Data Objects are a collection of classes and interfaces that manage database access within the .Net Framework. Entity framework is an open-source object-relational mapping (ORM) framework which sits on top of ADO.Net and provides a much easier interface for working with the objects.

Let's first start by looking at ADO.Net.

ADO.Net Object Model

ADO Object Model
ADO Object Model

The database on the server (MSSql, Oracle, MySql etc...) is accessed by ADO.Net using the SqlConnection object. A SqlCommand object is used to query the database and the results are stored in a SqlDataReader (connected mode) or a DataSet (disconnected mode) object. From these two objects, you can manipulate the data or present it with a data-aware control.

Connected mode means that the connection between the client and server is always open, disconnecting means that once the query has run, the data set is stored in memory and the connection is closed.

Connecting to Databases in Connected Mode

C#
string connectionString = @"Data Source=.SQLEXPRESS;AttachDbFilename=""C:SQL Server 2000Sample DatabasesNORTHWND.MDF"";Integrated Security=True;Connect Timeout=30;User Instance=True";

SqlConnection sqlCon = new SqlConnection(connectionString);
sqlCon.Open();

string commandString = "SELECT * FROM Customers";
SqlCommand sqlCmd = new SqlCommand(commandString, sqlCon);
SqlDataReader dataReader = sqlCmd.ExecuteReader();

while (dataReader.Read())
{
  Console.WriteLine(String.Format("{0} {1}", dataReader["CompanyName"], dataReader["ContactName"]));
}
dataReader.Close();
sqlCon.Close();

As we have said previously, the SqlDataReader works in connected mode, so each call to SqlDataReader.Read will stream data from the server. It is also sequential, so once a record has been read, you can't access it again without executing the sqlCommand.ExecuteReader method again. The time between sqlCon.Open() and sqlCon.Close() there is a connection to the server. If your application opens the connection on start-up and doesn't close it until it exits you can cause unnecessary record or table locks. The way around this is by using a DataSet which will download a local copy of a subset of the main database that can be manipulated and changes sent back to the server later on.

Connecting to Databases in Disconnected Mode

The disconnected mode will execute a query on the server and return the results in a DataSet object. This DataSet can then be used to display data, modify, insert or delete records without a database connection. When all changes have been made, the changes are sent back to the server.

C#
string connectionString = @"Data Source=.SQLEXPRESS;AttachDbFilename=""C:SQL Server 2000Sample DatabasesNORTHWND.MDF"";Integrated Security=True;Connect Timeout=30;User Instance=True";

string commandString = "SELECT * FROM Customers";

DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter(commandString, connectionString);

da.Fill(ds,"Customers"); / Customers is the name of the DataTable
            
foreach (DataRow dr in ds.Tables[0].Rows)
{
  Console.WriteLine(String.Format("{0} {1}", dr[1].ToString(), dr[2].ToString())); 
}

Updating in Connected Mode

The important thing to remember about the connected mode is that updates are processed as a command is executed, whereas using Disconnected methods allows the data to be previewed and further amended before being committed to the server.

Additional SQL commands must be created after the first reader has been closed, or you will have to create new objects.

C#
string connectionString = @"Data Source=.SQLEXPRESS;AttachDbFilename=""C:SQL Server 2000Sample DatabasesNORTHWND.MDF"";Integrated Security=True;Connect Timeout=30;User Instance=True";

SqlConnection sqlCon = new SqlConnection(connectionString);
sqlCon.Open();

string commandString = "SELECT * FROM Customers";
SqlCommand sqlCmd = new SqlCommand(commandString, sqlCon);
SqlDataReader dataReader = sqlCmd.ExecuteReader();

while (dataReader.Read())
{
  Console.WriteLine(String.Format("{0} {1}", dataReader["CompanyName"], dataReader["ContactName"]));
}
dataReader.Close();

commandString = "UPDATE Customers SET ContactName = 'Jane Doe' WHERE CustomerID = 'ALFKI'";
sqlCmd = new SqlCommand(commandString,sqlCon);
sqlCmd.ExecuteNonQuery();
            
sqlCon.Close();

Updating in Disconnected Mode

Disconnected updates are processed by manipulating the DataSet object. The Rows indexers access the record and the field.

C#
ds.Tables[0].Rows[0][2] = "Jane Doe";

You will also need to specify an Update or Insert command to the data adaptor to instruct the server on how it should update the table. Luckily there is a built-in tool to help with this called the SqlCommandBuilder.

C#
SqlCommandBuilder myBuilder = new SqlCommandBuilder(da);
da.UpdateCommand = myBuilder.GetUpdateCommand();

Changes to the DataSet are not committed to the server until the Update method is called from the DataAdapter.

C#
da.Update(ds, "Customers");

You can see all the updated records (or the records that have not been updated) by using a DataView and a DataViewRowState object. You can filter the current data grid view or you can create a new data grid view with only the updated records.

C#
DataView dv = new DataView(ds.Tables["Products"]);
dv.RowFilter = DataViewRowState.ModifiedCurrent;
dataGridView1.DataSource = dv;

Entity Framework

Now we have seen how the underlying mechanisms work, we can take a look at how Entity Framework works and how to interact with data in a much more convenient way.

Entity Framework enables developers to work with data using objects of domain-specific classes without focusing on the underlying database tables and columns where this data is stored.

With the Entity Framework, developers can work at a higher level of abstraction when they deal with data and can create and maintain data-oriented applications with less code compared with traditional applications.

Entity Data Model

The very first task of the Entity Framework API is to build an Entity Data Model (EDM). EDM is an in-memory representation of the entire metadata - its conceptual model, storage model, and mappings between them.

Entity Framework translates LINQ-to-Entities queries to SQL queries for relational databases using the EDM and also converts results back to entity objects.

EF API infers INSERT, UPDATE, and DELETE commands based on the state of entities when the SaveChanges() method is called. The ChangeTrack keeps track of the states of each entity as and when an action is performed.

Context Class in Entity Framework

The Context class in Entity Framework is a class which derives from DbContext. It is an important class in Entity Framework, which represents a session with the underlying database.

C#
public class OrderContext : DbContext
{
    public OrderContext()
    {
    }
        
    public DbSet<Items> Items { get; set; }
    public DbSet<Customer> StudentAddresses { get; set; }
    public DbSet<Grade> Grades { get; set; }
}

The context class is used to query or save data to the database. It is also used to configure domain classes, database-related mappings, change tracking settings, caching, transactions etc.

You can generate the context and entities for existing databases using EDM wizard integrated into Visual Studio.

This is done by adding a new item to the solution. Right-click on the project in the solution explorer, then Add, then New Item. This will open the Add New Item window. Select "ADO.NET Entity Data Model" and provide an appropriate name to the EDM click the Add button. This will show a connection wizard where you can connect to the database and include the tables and views you wish to include.

When you finish the wizard it will generate a .edmx file and add it to your project, along with the EDM classes. You can view these by expanding the created .tt T4 template file.

We can then go ahead and start querying our database using LINQ and our Entity Framework context.

Querying Data with Entity Framework

C#
using (var context = new OrderContext())
{
  var query = context.Orders
    .where(o => o.OrderNumber == "ABC123")
    .FirstOrDefault<Order>();
}

Insert Records with Entity Framework

We can do a simple DB insert by creating a new Order class and adding it to the context.

C#
using (var context = new OrderContext())
{
  var ord = new Order()  
  {
    OrderNumber = "DEF456",
    Customer = "Charlene Conner"
  };
  
  context.Orders.Add(ord);
  context.SaveChanges();
}

Updating Records with Entity Framework

We can update data in Entity Framework by easily querying for the existing data, updating the model and saving it back to the database.

C#
using (var context = new OrderContext())
{
  var ord = context.Orders.First<Order>(); 
  ord.Customer = "Gerard Valdez";
  context.SaveChanges();
}

Deleting Records with Entity Framework

Using a similar code pattern we can delete records as well.

C#
using (var context = new OrderContext())
{
  var ord = context.Orders.First<Order>();
  context.Orders.Remove(ord);
  context.SaveChanges();
}

ADO.Net Connection String Collection

This table contains a few of the more common connection strings for connecting ADO.Net to data sources other than SQL Server. It contains connection strings for MySql, Access, Excel, CSV and a few other files.

Microsoft SQL Server File (local)

C#
Data Source=(local); Initial Catalog=DatabaseName; Integrated Security=SSPI

Microsoft SQL Server (server)

C#
Server=(hostname); Database=DatabaseName; Trusted_Connection=Yes

Active Directory Service (OLEDB)

C#
Provider=ADSDSOObject; User Id=username; Password=password

Microsoft JET (Access) (OLEDB)

C#
Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\some\path\filename.mdb
C#
Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\some\path\filename.mdb; Jet OLEDB:Database Password="MyDbPassword"

Microsoft Excel XLS

C#
Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\some\path\filename.xls; Extended Properties="Excel 8.0;HDR=Yes"

MySql

Please see the tutorial Connecting ASP.Net to MySql.

IBM DB2 / AS400 / iSeries

Please see the tutorial series Querying iSeries DB2 with ADO.Net.

Was this article helpful to you?
 

Related ArticlesThese articles may also be of interest to you

CommentsShare your thoughts in the comments below

If you enjoyed reading this article, or it helped you in some way, all I ask in return is you leave a comment below or share this page with your friends. Thank you.

This post has 5 comment(s). Why not join the discussion!

We respect your privacy, and will not make your email public. Learn how your comment data is processed.

  1. SV

    On Friday 23rd of March 2012, Shubendra Verma said

    This is one of the best article so far I've read online. thanks for sharing with us. You made it very simple and understandable. Over the internet, I was some good article too which also explained very well on this topic, for more discussion on these post check out following links....

    http://mindstick.com/Blog/50/Database%20Connection
    http://social.msdn.microsoft.com/forums/en-US/sqltools/thread/a42fc25d-8fb1-4867-b9c8-f56923741205

    At last! I would like to thanks everyone for yours valuable post.

  2. GO

    On Friday 25th of March 2011, gold said

    Which mode is good n appropriate to use connected or disconnect?

  3. CH

    On Monday 22nd of September 2008, chitranjan said

    use the following querry

    SqlCommand command = new SqlCommand(”INSERT serviceStation ( siteID, codeID, stationName, address1, address2, town, county, postcode, telNo, siteTypeID, statusID, salesAreaID, areaID, brandID, typeID, roadTypeM, roadTypeJ, roadTypeA, roadtypeAB, openHours, costCentre, asset, deliveryPoint, deliveryDepotID, pamAreaID, isCurrent, nrvFitted, tanksDetailsID, pumpID, compressorID, cathodicProtectionID, siteCount, ERP, shell, telemetryInstalled, temperatureCompensationDtvcInstalled, cocaWwcUpgradeInstalled) VALUES ( @siteID, @codeID, @stationName, @address1, @address2, @town, @county, @postcode, @telNo, @siteTypeID, @statusID, @salesAreaID, @areaID, @brandID, @typeID, @roadTypeM, @roadTypeJ, @roadTypeA, @roadtypeAB, @openHours, @costCentre, @asset, @deliveryPoint, @deliveryDepotID, @pamAreaID, @isCurrent, @nrvFitted, @tanksDetailsID, @pumpID, @compressorID, @cathodicProtectionID, @siteCount, @ERP, @shell, @telemetryInstalled, @temperatureCompensationDtvcInstalled, @cocaWwcUpgradeInstalled)”, myDBSQLConnection);

    i hope this probleb is short out

  4. ST

    On Friday 15th of August 2008, Stapes said

    Updating in Disconnected Mode

    I tried using this technique. However, a lot of extra bits are required that are not shown here.

    The first time I ran:
    dataAdaptor2.Update(dsServiceStation, "[serviceStation]");

    I got the error:
    Update requires a valid InsertCommand when passed DataRow collection with new rows.

    So I added an insert command:

    SqlCommand command = new SqlCommand("INSERT INTO serviceStation ( siteID, codeID, stationName, address1, address2, town, county, postcode, telNo, siteTypeID, statusID, salesAreaID, areaID, brandID, typeID, roadTypeM, roadTypeJ, roadTypeA, roadtypeAB, openHours, costCentre, asset, deliveryPoint, deliveryDepotID, pamAreaID, isCurrent, nrvFitted, tanksDetailsID, pumpID, compressorID, cathodicProtectionID, siteCount, ERP, shell, telemetryInstalled, temperatureCompensationDtvcInstalled, cocaWwcUpgradeInstalled) VALUES ( @siteID, @codeID, @stationName, @address1, @address2, @town, @county, @postcode, @telNo, @siteTypeID, @statusID, @salesAreaID, @areaID, @brandID, @typeID, @roadTypeM, @roadTypeJ, @roadTypeA, @roadtypeAB, @openHours, @costCentre, @asset, @deliveryPoint, @deliveryDepotID, @pamAreaID, @isCurrent, @nrvFitted, @tanksDetailsID, @pumpID, @compressorID, @cathodicProtectionID, @siteCount, @ERP, @shell, @telemetryInstalled, @temperatureCompensationDtvcInstalled, @cocaWwcUpgradeInstalled)", myDBSQLConnection);

    dataAdaptor2.InsertCommand = command;

    Now I get the error:

    Must declare the scalar variable "@siteID".

    How come I need to declare it, when it should be explicit in the command:

    dataAdaptor2.Update(dsServiceStation, "[serviceStation]");

  5. Tim Trott

    On Friday 15th of August 2008, Tim Trott  Post Author said

    Stapes,

    You are correct in that a vital piece of information was missing, but you do not need to write the query statements yourself, you can use a SqlCommandBuilder instead.

    I have updated the article to include this information, you should be able to substitute Update for Insert.

    Hope that helps.