xpo-2123-connect-to-a-data-store.md
To use XPO with your database server, add a required database provider assembly to your project’s references. See the following topic for details: Database Systems Supported by XPO.
Call the GetDataLayer(String, AutoCreateOption) method and pass a connection string or existing connection object to this method as a parameter. This method creates a Data Access Layer (DAL) object.
Use the newly created DAL to create UnitOfWork or Session objects:
using System;
using System.Linq;
using DevExpress.Xpo;
namespace XpoConsoleApp {
class Program {
static void Main(string[] args) {
// Connect to an in-memory source
const string connectionString = @"XpoProvider=InMemoryDataStore;Data Source=.\mydatabase.xml;Read Only=false";
var inMemoryDAL = XpoDefault.GetDataLayer(connectionString, DevExpress.Xpo.DB.AutoCreateOption.DatabaseAndSchema);
// Create and save a new data object
using(var uow = new UnitOfWork(inMemoryDAL)) {
var contact = new Contact(uow);
contact.FirstName = "Alice";
contact.LastName = "Smith";
uow.CommitChanges();
}
// Read the new data object
using(var uow = new UnitOfWork(inMemoryDAL)) {
var contact = uow.Query<Contact>().FirstOrDefault(c => c.LastName == "Smith");
Console.WriteLine(contact.FirstName + " " + contact.LastName);
}
}
}
public class Contact : XPObject {
public string FirstName {
get { return fFirstName; }
set { SetPropertyValue(nameof(FirstName), ref fFirstName, value); }
}
string fFirstName;
public string LastName {
get { return fLastName; }
set { SetPropertyValue(nameof(LastName), ref fLastName, value); }
}
string fLastName;
public Contact(Session session) : base(session) { }
}
}
Imports DevExpress.Xpo
Namespace XpoConsoleApp
Friend Class Program
Private Shared Sub Main(ByVal args As String())
' Connect to an in-memory source
Const connectionString As String = "XpoProvider=InMemoryDataStore;Data Source=.\mydatabase.xml;Read Only=false"
Dim inMemoryDAL = XpoDefault.GetDataLayer(connectionString, DevExpress.Xpo.DB.AutoCreateOption.DatabaseAndSchema)
' Create and save a new data object
Using uow = New UnitOfWork(inMemoryDAL)
Dim contact = New Contact(uow)
contact.FirstName = "Alice"
contact.LastName = "Smith"
uow.CommitChanges()
End Using
' Read the new data object
Using uow = New UnitOfWork(inMemoryDAL)
Dim contact = uow.Query(Of Contact)().FirstOrDefault(Function(c) c.LastName Is "Smith")
Console.WriteLine(contact.FirstName + " " + contact.LastName)
End Using
End Sub
End Class
Public Class Contact
Inherits XPObject
Public Property FirstName As String
Get
Return fFirstName
End Get
Set(ByVal value As String)
SetPropertyValue(NameOf(Contact.FirstName), fFirstName, value)
End Set
End Property
Private fFirstName As String
Public Property LastName As String
Get
Return fLastName
End Get
Set(ByVal value As String)
SetPropertyValue(NameOf(Contact.LastName), fLastName, value)
End Set
End Property
Private fLastName As String
Public Sub New(ByVal session As Session)
MyBase.New(session)
End Sub
End Class
End Namespace
You can create a default DAL and use it in any scope of your application.
Use the XpoDefault.DataLayer static property to get or set a default data layer.
To use a default DAL, create UnitOfWork or Session objects using parameterless constructors:
using System;
using System.Linq;
using DevExpress.Xpo;
namespace XpoConsoleApp {
class Program {
static void Main(string[] args) {
// Connect to an in-memory source
const string connectionString = @"XpoProvider=InMemoryDataStore;Data Source=.\mydatabase.xml;Read Only=false";
XpoDefault.DataLayer = XpoDefault.GetDataLayer(connectionString, DevExpress.Xpo.DB.AutoCreateOption.DatabaseAndSchema);
// Create and save a new data object
// This Unit of Work uses a default Data Access Layer
using(var uow = new UnitOfWork()) {
var contact = new Contact(uow);
contact.FirstName = "Alice";
contact.LastName = "Smith";
uow.CommitChanges();
}
// Read a data object
// This Unit of Work uses a default Data Access Layer
using(var uow = new UnitOfWork()) {
var contact = uow.Query<Contact>().FirstOrDefault(c => c.LastName == "Smith");
Console.WriteLine(contact?.FirstName + " " + contact?.LastName);
}
}
}
public class Contact : XPObject {
// ...
public Contact(Session session) : base(session) { }
}
}
Imports DevExpress.Xpo
Namespace XpoConsoleApp
Friend Class Program
Private Shared Sub Main(ByVal args As String())
' Connect to an in-memory source
Const connectionString As String = "XpoProvider=InMemoryDataStore;Data Source=.\mydatabase.xml;Read Only=false"
XpoDefault.DataLayer = XpoDefault.GetDataLayer(connectionString, DevExpress.Xpo.DB.AutoCreateOption.DatabaseAndSchema)
' Create and save a new data object
' This Unit of Work uses a default Data Access Layer
Using uow = New UnitOfWork()
Dim contact = New Contact(uow)
contact.FirstName = "Alice"
contact.LastName = "Smith"
uow.CommitChanges()
End Using
' Read a data object
' This Unit of Work uses a default Data Access Layer
Using uow = New UnitOfWork()
Dim contact = uow.Query(Of Contact)().FirstOrDefault(Function(c) c.LastName Is "Smith")
Console.WriteLine(contact?.FirstName + " " + contact?.LastName)
End Using
End Sub
End Class
Public Class Contact
Inherits XPObject
' ...
Public Sub New(ByVal session As Session)
MyBase.New(session)
End Sub
End Class
End Namespace
Tip
You can also specify a connection string in the following ways:
Refer to the property descriptions for more information.
A connection to a data store is established in the following cases:
If you use the XpoDefault.GetDataLayer or XpoDefault.GetConnectionProvider method, XPO keeps the connection open until the application is stopped or restarted.
To change the database connection without restarting the application, use the following overloaded methods:
These methods have an additional out parameter that initializes a variable with an array of IDisposable objects: objectsToDisposeOnDisconnect.
using DevExpress.Xpo;
using DevExpress.Xpo.DB;
using DevExpress.Xpo.Metadata;
// ...
static IDisposable[] ObjectsToDisposeOnDisconnect;
static Lazy<XPDictionary> SharedDictionary = new Lazy<XPDictionary>(CreateSharedDictionary);
static void ChangeConnection(string connectionString) {
if(ObjectsToDisposeOnDisconnect != null) {
foreach(IDisposable toDispose in ObjectsToDisposeOnDisconnect)
toDispose.Dispose();
}
XpoDefault.DataLayer = XpoDefault.GetDataLayer(connectionString, SharedDictionary.Value, AutoCreateOption.SchemaAlreadyExists, out ObjectsToDisposeOnDisconnect);
}
static XPDictionary CreateSharedDictionary() {
XPDictionary result = new ReflectionDictionary();
result.GetDataStoreSchema(typeof(Contact).Assembly);
return result;
}
Imports DevExpress.Xpo
Imports DevExpress.Xpo.DB
Imports DevExpress.Xpo.Metadata
' ...
Private Shared ObjectsToDisposeOnDisconnect() As IDisposable
Private Shared SharedDictionary As New Lazy(Of XPDictionary)(CreateSharedDictionary)
Shared Sub ChangeConnection(ByVal connectionString As String)
If ObjectsToDisposeOnDisconnect IsNot Nothing Then
For Each toDispose As IDisposable In ObjectsToDisposeOnDisconnect
toDispose.Dispose()
Next toDispose
End If
XpoDefault.DataLayer = XpoDefault.GetDataLayer(connectionString, SharedDictionary.Value, AutoCreateOption.SchemaAlreadyExists, ObjectsToDisposeOnDisconnect)
End Sub
Shared Function CreateSharedDictionary() As XPDictionary
Dim result As XPDictionary = New ReflectionDictionary()
result.GetDataStoreSchema(GetType(Contact).Assembly)
Return result
End Function
If you want to control the connection state (open/closed), create an IDbConnection object and use a constructor to pass the object to a Data Store Provider.
using DevExpress.Xpo;
using DevExpress.Xpo.DB;
using Microsoft.Data.SqlClient;
// ...
SqlConnection Connection;
void Connect(string connectionString) {
Connection = new SqlConnection(connectionString);
MSSqlConnectionProvider dataStoreProvider = new MSSqlConnectionProvider(Connection, AutoCreateOption.SchemaAlreadyExists);
XpoDefault.DataLayer = new SimpleDataLayer(dataStoreProvider);
}
Imports DevExpress.Xpo
Imports DevExpress.Xpo.DB
Imports Microsoft.Data.SqlClient
' ...
Private Connection As SqlConnection
Private Sub Connect(ByVal connectionString As String)
Connection = New SqlConnection(connectionString)
Dim dataStoreProvider As New MSSqlConnectionProvider(Connection, AutoCreateOption.SchemaAlreadyExists)
XpoDefault.DataLayer = New SimpleDataLayer(dataStoreProvider)
End Sub
If you use the ConnectionString or Connection property, the connection is alive while a session is active (until the Session.Disconnect method is explicitly called). This method is called implicitly when you dispose of a Session object.
A data store provider is an IDataStore implementation. It connects individual data stores ( Microsoft SQL Server , MySQL databases, etc.)
See also: DataStoreBase.
A data access layer ( DAL ) (an IDataLayer implementation) uses object access layers to enable a unified access to data stores (loading data from a data store, updating its data and schema).
XPO includes the following data access layer implementations:
In general, SimpleDataLayer is equal to ThreadSafeDataLayer , and the substitution of one component by another has no effect. However, you cannot use SimpleDataLayer or ThreadSafeDataLayer under the circumstances described below:
See also: How to Resolve ‘Cannot Modify Dictionary because ThreadSafeDataLayer Uses It’
Each Session or UnitOfWork object creates a new DAL when a connection to a data store is about to be established. You can force a Session or UnitOfWork to use an existing DAL. In this case, specific initialization steps are omitted and the connection is established faster.
To make a session use a specific DAL, do one of the following:
See also: IDataLayerAsync.
An object access layer ( OAL ) is a mediator between a Session or UnitOfWork and a data access layer. An OAL translates object queries and storage schema updates to corresponding statements, and passes them to a data access layer for execution.
XPO has the following object access layer implementations.
DevExpress.Xpo.SessionObjectLayer - Created for nested units of work. This object layer uses a parent unit of work as a data source.See also: IObjectLayerAsync.
Note
You can try the functionality described here in the Connecting to a Data Store section of the XPO Tutorials demo (C:\Users\Public\Documents\DevExpress Demos 25.2\Components\WinForms\Bin\XpoTutorials.exe).