ADO The origin of data access in .NET

ADO The origin of data access in .NET

.NET communicates with a database using ADO.NET, which provides a set of classes and interfaces for accessing and manipulating data stored in a database.

ADO.NET supports various database systems, including relational databases and XML databases.

ADO.NET uses the following protocols to communicate with a database:

1. OLE DB (Object Linking and Embedding, Database) – This is a low-level, component-based API that provides a generic interface for accessing various types of data sources, including relational databases, spreadsheet data, and more.

2. ODBC (Open Database Connectivity) – This is a widely used API for accessing relational databases. It provides a standardized interface for accessing data, regardless of the underlying database management system.

3. ADO.NET Provider – This is a high-level, .NET-based API for accessing data stored in a specific database management system, such as Microsoft SQL Server, Oracle, or MySQL.

The choice of protocol used by ADO.NET to communicate with a database depends on the specific requirements of the application and the database management system being used.

The ADO.NET provider approach is the most common and provides a flexible and scalable solution for accessing and manipulating data stored in a database, supporting a wide range of database systems and communication protocols.

ADO.NET Main Components

The main classes in ADO.NET include:

1. Connection – Represents a connection to a database, providing methods for opening and closing a connection and for executing commands against the database.

2. Command – Represents a database command, such as a SELECT, INSERT, UPDATE, or DELETE statement, and provides methods for executing the command and for retrieving the results of the command.

3. DataReader – Provides a forward-only, read-only view of the results of a command. The DataReader is optimized for retrieving large amounts of data from a database, as it retrieves data in a streaming manner, rather than retrieving all data into memory at once.

4. DataAdapter – Represents a set of data commands and a database connection that are used to fill a DataSet and to resolve changes made to the data back to the database. The DataAdapter is often used in combination with a DataSet to provide a flexible and scalable way to access and manipulate data stored in a database.

5. DataSet – Represents an in-memory cache of data, providing a disconnected view of data that can be used to work with data independently of a database connection. The DataSet provides a rich set of features for manipulating and querying data, including support for relationships between tables, constraints, and transactions.

6. Parameter – Represents a parameter for a database command, providing a way to specify input values for a command, such as the values for parameters in a stored procedure.

These are the main classes in ADO.NET, and they provide a comprehensive and flexible set of tools for accessing and manipulating data stored in a database.

Design problems in ADO.NET 1

ADO.NET 1 refers to the first version of ADO.NET, which was introduced in .NET Framework 1.0, released in 2002. In this version of ADO.NET, data access was performed using direct methods and properties of the various ADO.NET classes, such as SqlConnection and SqlCommand for SQL Server.

The main design problem for ADO.NET 1 is that it requires developers to write database-specific code for each database management system that they wanted to access.

ADO.NET 2 and the DbProviderFactory

With the introduction of .NET Framework 2.0 in 2005, the ADO.NET DbProviderFactory was introduced.

The DbProviderFactory abstract class provides a set of methods for creating database-specific implementations of various ADO.NET classes, such as DbConnection, DbCommand, and DbDataAdapter, and makes it easier for developers to write database-agnostic code.

ADO.NET DbProviderFactory is a factory pattern that provides a standard way to create instances of database-specific classes, such as connection and command classes, in ADO.NET.

The DbProviderFactory is used by the ADO.NET data providers, such as the SqlClient data provider for SQL Server, the OleDb data provider for OLE DB data sources, and the ODBC data provider for ODBC data sources, to provide a common way to create instances of the classes that they implement. This makes it easier for developers to switch between different data providers and to write database-agnostic code that can work with different databases without modification.

The introduction of DbProviderFactory in ADO.NET was an exceptional milestone that revolutionized database access in .NET. By providing a standardized interface for creating database-specific connection objects, DbProviderFactory enhanced the flexibility and portability of data access code. Its ingenious design allowed developers to write data access logic without being tightly coupled to a specific database provider, thereby promoting code reusability and adaptability. This breakthrough was the steppingstone to the emergence and widespread adoption of Object-Relational Mapping Systems (ORMs).

ORMs leveraged DbProviderFactory’s capabilities to abstract the complexities of database interactions and map database entities to object-oriented representations seamlessly. As a result, developers could focus more on business logic and application development rather than dealing with low-level data access intricacies.

The symbiotic relationship between DbProviderFactory and ORMs continues to shape modern software development, empowering developers with powerful tools to efficiently manage and manipulate data in a database-agnostic manner.

Until next time ))

We are excited to announce that we are currently in the process of writing a comprehensive book about DevExpress XPO. As we work on this project, we believe it is essential to involve our readers and gather their valuable feedback. Therefore, we have decided to share articles from the book as we complete them, giving you an opportunity to provide input and suggestions that we can consider for inclusion in the final release. Keep in mind that the content presented is subject to change. We greatly appreciate your participation in this collaborative effort.

Related Articles

Relational database systems: the holy grail of data

 

Relational database systems: the holy grail of data

Relational database systems: the holy grail of data

RDBMS stands for Relational Database Management System. It is a type of database management system that is based on the relational model, which organizes data into tables with rows and columns, and uses relationships between tables to link data together.

In an RDBMS, data is stored in tables, with each table representing a specific type of data (such as customers, orders, or products). Each table has columns that represent the attributes of the data, and rows that represent individual instances of the data. Relationships between tables can be established using keys, allowing data from multiple tables to be linked and retrieved in a single query.

RDBMSs provide a variety of features and tools for managing, querying, and manipulating data stored in the database, including data validation, constraint enforcement, transaction management, backup and recovery, reporting and analysis capabilities. They are widely used in enterprise applications, web applications, and other systems that require the management of large amounts of structured data.

Examples of popular RDBMSs include Oracle, Microsoft SQL Server, MySQL, and PostgreSQL.

A Relational Database Management System (RDBMS) uses Data Manipulation Language (DML) and Data Definition Language (DDL) queries to interact with the data stored in the database. The specific syntax of the queries will vary depending on the database system being used.

DML queries are used to retrieve, insert, update, and delete data in the database. The most used DML queries are:

  • SELECT: Retrieves data from one or more tables in the database.
  • INSERT: Adds a new row of data to a table in the database.
  • UPDATE: Modifies existing data in a table in the database.
  • DELETE: Deletes data from a table in the database.

DDL queries are used to create, modify, and delete database structures, such as tables, indexes, and constraints. The most used DDL queries are:

  • CREATE: Creates a new database object, such as a table or index.
  • ALTER: Modifies the structure of an existing database object.
  • DROP: Deletes a database object.

 

For example, the following is a DDL query to create a table named customers:

CREATE TABLE customers (

  id INT PRIMARY KEY AUTO_INCREMENT,

  name VARCHAR(255),

  email VARCHAR(255),

  address VARCHAR(255)

);

 

And the following is a DML query to insert a new customer into the customers table:

INSERT INTO customers (name, email, address)

VALUES ('John Doe', 'johndoe@example.com', '123 Main St');

In the next article we will be talking about the origin of data access in net framework  a.k.a ADO.NET

See you then )))

We are excited to announce that we are currently in the process of writing a comprehensive book about DevExpress XPO. As we work on this project, we believe it is essential to involve our readers and gather their valuable feedback. Therefore, we have decided to share articles from the book as we complete them, giving you an opportunity to provide input and suggestions that we can consider for inclusion in the final release. Keep in mind that the content presented is subject to change. We greatly appreciate your participation in this collaborative effort.

 

Querying external data sources in XAF

Querying external data sources in XAF

I will explain what XAF is just for the sake of the consistency of this article, XAF is a low code application framework for line of business applications that runs on NET framework (windows forms and web forms) and in dotnet (windows forms, Blazor and Web API)

XAF is laser focus on productivity, DevExpress team has created several modules that encapsulate design patterns and common tasks needed on L.O.B apps.

The starting point in XAF is to provide a domain model using an ORMs like XPO or Entity framework and then XAF will create an application for you using the target platform of choice.

It’s a common misunderstanding that you need to use and ORM in order to provide a domain model to XAF

DevExpress team has created ObjectSpace abstraction so XAF can be extended to use different data access technologies ( you can read more about it here https://docs.devexpress.com/eXpressAppFramework/DevExpress.ExpressApp.BaseObjectSpace)

Out of the box XAF provide 3 branches of object spaces as show is the graph below.

XPObjectSpace: this is the object space that allows you to use XPO as a data access technology.

EfCoreObjectSpace: this is the object space that allows you to use Microsoft Entity Framework as a data access technology.

NonPersistenObjectSpace: this object space is interesting as it provides the domain model needed for XAF to generate the views and interact with the data is not attached to an ORM technology so it’s up to us to provide the data, also this type of object space can be used in combination with XPObjectSpace and EfCoreObjectSpace

 

When querying external data sources, you also need to solve the problem of filtering and sorting data in order to provide a full solution, for that reason DevExpress team provide us with the DynamicCollection class, that is a proxy collection that allows you to filter and sort an original collection without changing it.

Now that we know the parts involved in presenting data in a XAF application, we can define the required flow.

 

    [DefaultClassOptions]
    [DefaultProperty(nameof(Article.Title))]
    [DevExpress.ExpressApp.ConditionalAppearance.Appearance("", Enabled = false, TargetItems = "*")]
    [DevExpress.ExpressApp.DC.DomainComponent]
    public class Article : NonPersistentObjectBase {
        internal Article() { }

 

    public override void Setup(XafApplication application) {
        base.Setup(application);
        // Manage various aspects of the application UI and behavior at the module level.
        application.SetupComplete += Application_SetupComplete;
    }

 

  • Wire the application object space created event.
private void Application_SetupComplete(object sender, EventArgs e) {
    Application.ObjectSpaceCreated += Application_ObjectSpaceCreated;
}
private void Application_ObjectSpaceCreated(object sender, ObjectSpaceCreatedEventArgs e) {
    var npos = e.ObjectSpace as NonPersistentObjectSpace;
    if (npos != null) {
        new ArticleAdapter(npos);
        new ContactAdapter(npos);
    }
}

 

public ArticleAdapter(NonPersistentObjectSpace npos) {
     this.objectSpace = npos;
     objectSpace.ObjectsGetting += ObjectSpace_ObjectsGetting;
 }

 

private void ObjectSpace_ObjectsGetting(object sender, ObjectsGettingEventArgs e) {
     if(e.ObjectType == typeof(Article)) {
         var collection = new DynamicCollection(objectSpace, e.ObjectType, e.Criteria, e.Sorting, e.InTransaction);
         collection.FetchObjects += DynamicCollection_FetchObjects;
         e.Objects = collection;
     }
 }
 private void DynamicCollection_FetchObjects(object sender, FetchObjectsEventArgs e) {
     if(e.ObjectType == typeof(Article)) {
         e.Objects = articles;
         e.ShapeData = true;
     }
 }

Full source code here

In conclusion the ObjectSpace abstraction ensures that different data access technologies can be employed, while the DynamicCollection class allows for seamless filtering and sorting of data from external sources. By following the outlined steps, developers can create robust, adaptable, and efficient applications with XAF, ultimately saving time and effort while maximizing application performance.

the myth of “it is better not to use a framework”

the myth of “it is better not to use a framework”

based on my experience with numerous application frameworks, I regard XAF as the most efficient in delivering robust solutions quickly and with minimal code. Our company has trained over 100 software firms in utilizing eXpressApp Framework (XAF) and XPO, leading me to believe that the issue typically stems from three factors:

The illusion of productivity

Many software developers perceive themselves as more productive when not using frameworks, as they often associate productivity with the volume of code they produce. This frequently involves reinventing the wheel, and more code does not necessarily bring them closer to their goals.

Grasping the business requirements

This factor is connected to the first, as an unclear or poorly understood business requirement can lead programmers to focus on trivial tasks, such as adding a row to a database, instead of tackling complex business scenarios. As a result, the application framework might be seen as an obstacle by the development team, since it already addresses basic tasks and forces them to confront challenging business problems early on, which they may then attribute to the framework.

Familiarity with both the application framework and the business problem

These two aspects are the primary challenges in Line-of-Business (LOB) software development. The general principle is that one must be equally well-versed in the business problem and the application framework. The worst-case scenario arises when there is limited technical knowledge and high business demands, which, surprisingly, is the most common situation.

In conclusion, the efficiency and effectiveness of application frameworks, such as XAF, in delivering robust solutions with minimal code are often undervalued due to misconceptions and challenges that developers face. Overcoming the illusion of productivity, ensuring a clear understanding of business requirements, and achieving a balance between technical and business expertise are crucial for harnessing the full potential of application frameworks. By addressing these challenges, development teams can unlock the true power of XAF and similar frameworks, streamlining the development process and paving the way for more successful software solutions that cater to complex business needs.

Replacing WCF with AspNetCore Rest API as transport layer for XPO

Replacing WCF with AspNetCore Rest API as transport layer for XPO

I have been using XPO from DevExpress since day one. For me is the best O.R.M in the dot net world, so when I got the news that XPO was going to be free of charge I was really happy because that means I can use it in every project without adding cost for my customers.

Nowadays all my customer needs some type of mobile development, so I have decided to master the combination of XPO and Xamarin

Now there is a problem when using XPO and Xamarin and that is the network topology, database connections are no designed for WAN networks.

Let’s take MS SQL server as an example, here are the supported communication protocols

  • TCP/IP.
  • Named Pipes

To quote what Microsoft web site said about using the protocols above in a WAN network

https://docs.microsoft.com/en-us/sql/tools/configuration-manager/choosing-a-network-protocol?view=sql-server-2014

Named Pipes vs. TCP/IP Sockets

In a fast-local area network (LAN) environment, Transmission Control Protocol/Internet Protocol (TCP/IP) Sockets and Named Pipes clients are comparable with regard to performance. However, the performance difference between the TCP/IP Sockets and Named Pipes clients becomes apparent with slower networks, such as across wide area networks (WANs) or dial-up networks. This is because of the different ways the interprocess communication (IPC) mechanisms communicate between peers.”

So, what other options do we have? Well if you are using the full DotNet framework you can use WCF.

So, it looks like WCF is the solution here since is mature and robust communication framework but there is a problem, the implementation of WCF for mono touch (Xamarin iOS) and mono droid (Xamarin Android)

You can read about Xamarin limitations in the following links

Android: https://docs.microsoft.com/en-us/xamarin/android/internals/limitations

iOS: https://docs.microsoft.com/en-us/xamarin/ios/internals/limitations

I don’t want to go into details about how the limitation of each platform affects XPO and WCF but basically the main limitation is the ability to use reflection and emit new code which is needed to generate the WCF client, also in WCF there are problems in the serialization behaviors.

Well now that we know the problem is time to talk about the solution. As you know XPO has a layered architecture ( you can read about that here https://www.jocheojeda.com/2018/10/01/xpo-post-5-layered-architecture/)

So basically, what we need to do is to replace the WCF layer with some other technology to communicate to the database server

The technology I’ve selected for this AspNetCore which I would say is a really nice technology that is modern, multi-platform and easy to use. Here below you can see what is the architecture of the solution

AspNetCore

Rest API

So, what we need basically is to be able to communicate the data layer with the data store through a network architecture.

The network architecture that I have chosen is a rest API which is one of the strong fronts of AspNetCore. The rest API will work as the server that forward the communication from XPO to the Database and vice versa, you can find a project template of the server implementation here https://www.jocheojeda.com/download/560/ this implementation references one nuget where I have written the communication code, you can fine the nuget here https://nuget.bitframeworks.com/feeds/main/BIT.Xpo.AgnosticDataStore.Server/19.1.5.1

Also we need a client that is able to interpret the information from the rest API and feed XPO, for that I have created a special client you can find here https://nuget.bitframeworks.com/feeds/main/BIT.Xpo.AgnosticDataStore.Client/19.1.5.1

The client implementation has been tested in the following platforms

  • Xamarin Android
  • Xamarin iOS
  • Xamarin WPF
  • DotNetCore
  • DotNetFramework

The client implementation has been tested in the following operative systems

  • Android 5 to 9
  • iOS 9 to 11
  • MacOS: Sierra to Catalina
  • Windows 10

In this link, you can see a full implementation of the server and the clients (XAF and Xamarin)

What is next? Well here are a few topics for the upcoming posts

  • Understanding JWT tokens
  • How to secure your data store service with a JWT token
  • Hosting multiple data store with a single service
  • Implementing your own authentication method
  • Examples examples examples

 

Exposing your XPO ORM using GraphQL dotnet

Exposing your XPO ORM using GraphQL dotnet

Exposing your XPO ORM using GraphQL

Note: you can download the full source code for this article in my GitHub repository 

In the past few years, I have been working on developing mobile applications, in the mobile world most of the applications will consume some type of data service, the main problem here is how to choose the correct data service? There are a lot of technologies to expose data over the wire and all of them are good somehow, so for me, the quest is about to find a technology where can I use my current skill set.

Today subject of study is GraphQL, an open source technology developed by Facebook that is a data query and manipulation language for API.

The beauty of GraphQL is its efficient and flexible approach to develop web APIs that can be queried to return a different data structure in the opposite side of the REST API and traditional web services that return a fix data structure, you can learn more about the GrahpQL project on their website https://graphql.org/

First, we will start by creating a new Asp.net core web application

A screenshot of a cell phone Description automatically generated

We name the application

A screenshot of a cell phone Description automatically generated

Then we select Empty for the project type

A screenshot of a cell phone Description automatically generated

Now that the project is created, we need to add a few NuGet packages, you can copy and paste the following snippet inside of your csproj file

<ItemGroup>

<PackageReference Include="DevExpress.Xpo" Version="18.2.7" />

<PackageReference Include="GraphQL" Version="2.4.0" />

<PackageReference Include="GraphQL.Server.Transports.AspNetCore" Version="3.4.0" />

<PackageReference Include="GraphQL.Server.Transports.WebSockets" Version="3.4.0" />

<PackageReference Include="Microsoft.AspNetCore.App" />

<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />

<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />

<PackageReference Include="Microsoft.Data.Sqlite" Version="2.2.4" />

<PackageReference Include="System.Reactive" Version="4.1.5" />

</ItemGroup>

 

Now if let’s try to compile and run the application, at this moment you should see a “hello world” in your browser

A screenshot of a cell phone Description automatically generated

Now let’s add a second project to the solution to host the ORM, for that let’s use a NetStandard class library

A screenshot of a cell phone Description automatically generated

Let’s name the project XpoOrm, then edit the project file and add the following NuGet packages

<ItemGroup>

<PackageReference Include="DevExpress.Xpo" Version="18.2.7" />

<PackageReference Include="GraphQL" Version="2.4.0" />

<PackageReference Include="GraphQL.Server.Transports.AspNetCore" Version="3.4.0" />

<PackageReference Include="GraphQL.Server.Transports.WebSockets" Version="3.4.0" />

<PackageReference Include="System.Reactive" Version="4.1.5" />

</ItemGroup>

 

Now let’s add 3 folders, schema, services and models

A close up of a logo Description automatically generated

The basic structure of our project is ready, so let’s start adding some models, we will add 2 models products and categories, you can get the source of the files here

A screenshot of a cell phone Description automatically generated

A screenshot of a cell phone Description automatically generated

When you finish implementing the models the next step is to implement the services, remember that the main goal of GraphQL is to create a queryable layer between the client and the data service, you can architecture your service in the way that is more convenient for you but in this case I will create one service per entity, this services will be injected in our application using asp.net dependency injection. You can find the source for the services here

Product Service

A screenshot of a cell phone Description automatically generated

Category Service

A screenshot of a cell phone Description automatically generated

So far there we have not written any code related to GraphQL so now it’s the time. GraphQL does not directly expose your data model class instead it builds a type based on your model, let’s see how this will work for the Category model

A screenshot of a cell phone Description automatically generated

As you can see, I have created a new class that inherits from ObjectGraphType<T> where T is our XPO persistent class. Also, in the constructor I used the fluent API to map the fields from the category model to the CategoryType class, the method Field contains several overloads so you can do any type of crazy stuff in here, but for now I’m going keep it simple, now lets create the type for the product model.

A screenshot of a cell phone Description automatically generated

Now that we have created the ProductType class we can see that there are new characteristics here, the first new thing that you will notice is that in the constructor I injected the category service to load the category object related to the product, that is the common design pattern of GrahpQL, this approach is  useful if you are using POCO objects. Also, if you see the commented-out code you can see that when we use XPO we don’t need to inject the category service since it can be loaded directly from the instance of the Product class using XPO lazy loading feature. You can find both graph types here

Now that we have our graph types, we need to create 2 more classes, an object that will hold our list of queries and a schema object that will provide information about the types and the queries that we are exposing, let’s start with the queries object

A screenshot of a cell phone Description automatically generated

The Queries object is basically another graph type, but instead of exposing a model class is exposing the object class, it also uses the dependency injection to inject the 2 services that will forward the data to the fields. Now its time to create the schema for our GraphQL service

A screenshot of a cell phone Description automatically generated

A GraphQL schema can only expose one query so that is why I have created the object queries to hold all the possible subqueries of our services. As you can see, I injected the queries object and the dependency resolver, you can find the code for these classes here.

Now its time to go back to the asp.net core service and start the configuration of GrahpQL, let’s start with the program class

A screenshot of a cell phone Description automatically generated

As you can see in the main method there is some boilerplate code to initialize XPO data layer and create some sample data, nothing new if you are an XPO user you might be already familiar with this code. Now let’s move to the startup class

A screenshot of a cell phone Description automatically generated

As any asp.net core web application, there are 2 important methods let’s see what happened on each of them.

In the configure services method I register the services I created and the graph types also added the GraphQL service and the web sockets and data loader.

Now in the configure method I enabled the use of default files and static files, web sockets also I exposed the GrahpQL schema using web sockets and GrahpQL (this is the HTTP version of the API)

Our API is almost done, there is only one last step we need to do, we need a way to test our API for that we will use Graphical which is a web client to query GrahpQL APIs, the graphical project is hosted here https://github.com/graphql/graphiql but to make it simpler you can download the files from my GitHub repository here

Let’s create a wwwroot folder and add the graphical files into it

Run the application, you should see the graphical U.I and you should be able to navigate the API documentation

A screenshot of a social media post Description automatically generated

or you can query of XPO ORM

A screenshot of a social media post Description automatically generated

As you can see there is autocomplete on the query editor also we are able to query objects and nested objects on a field-based manner

This article is the first article on a series of how to expose any XPO ORM using GraphQL, in the next post we will learn about mutations