Files to look at:
- Program.cs (VB: Program.vb)
- SafePostgreSqlConnectionProvider.cs (VB: SafePostgreSqlConnectionProvider.vb)
This example demonstrates how to create an IDataStore wrapper for the PostgreSqlConnectionProvider and implement the functionality for recreating broken connections.
Does this example address your development requirements/objectives?
(you will be redirected to DevExpress.com to submit your response)
Example Code
C#using System;
using DevExpress.Xpo;
using DevExpress.Xpo.DB;
namespace B190497 {
class Program {
static void Main(string[] args) {
SafePostgreSqlConnectionProvider.Register();
SafePostgreSqlConnectionProvider dataStore = new SafePostgreSqlConnectionProvider(
"user id=postgres;password=admin;server=donchakDBFarm;database=XpoUnitTests;port=5434",
AutoCreateOption.DatabaseAndSchema
);
IDataLayer dal = new SimpleDataLayer(dataStore);
int id = CreateData(dal);
Console.WriteLine("restart the database, and press any key to continue ..");
Console.ReadKey();
new Session(dal).GetObjectByKey<Person>(id);
((IDisposable)dataStore).Dispose();
dal.Dispose();
Console.WriteLine("done\npress any key to exit ..");
Console.ReadKey();
}
static int CreateData(IDataLayer dal) {
using (UnitOfWork uow = new UnitOfWork()) {
Person result = uow.FindObject<Person>(null);
if (result == null) {
result = new Person(uow);
result.Name = "Uriah";
}
uow.CommitChanges();
return result.Oid;
}
}
}
public class Person : XPObject {
public Person(Session session) : base(session) { }
string fName;
public string Name {
get { return fName; }
set { SetPropertyValue<string>("Name", ref fName, value); }
}
}
}
C#using System;
using System.Data;
using DevExpress.Xpo.DB;
using DevExpress.Xpo.DB.Exceptions;
using System.Reflection;
using System.Globalization;
using DevExpress.Xpo.Helpers;
using Npgsql;
namespace B190497 {
public class SafePostgreSqlConnectionProvider : IDataStore, IDisposable, ICommandChannel {
PostgreSqlConnectionProvider InnerDataStore;
IDbConnection Connection;
string ConnectionString;
AutoCreateOption AutoCreateOption;
public static void Register() {
DataStoreBase.RegisterDataStoreProvider(PostgreSqlConnectionProvider.XpoProviderTypeString,
new DevExpress.Xpo.DB.Helpers.DataStoreCreationFromStringDelegate(CreateProviderFromString));
}
public static IDataStore CreateProviderFromString(string connectionString, AutoCreateOption autoCreateOption,
out IDisposable[] objectsToDisposeOnDisconnect) {
SafePostgreSqlConnectionProvider rv = new SafePostgreSqlConnectionProvider(connectionString, autoCreateOption);
objectsToDisposeOnDisconnect = new IDisposable[] { rv };
return rv;
}
public SafePostgreSqlConnectionProvider(string connectionString, AutoCreateOption autoCreateOption) {
this.ConnectionString = connectionString;
this.AutoCreateOption = autoCreateOption;
DoReconnect();
}
~SafePostgreSqlConnectionProvider() {
Dispose(false);
}
void DoReconnect() {
DoDispose(false);
Connection = PostgreSqlConnectionProvider.CreateConnection(ConnectionString);
InnerDataStore = new PostgreSqlConnectionProvider(Connection, AutoCreateOption);
}
void DoDispose(bool closeConnection) {
if (Connection != null) {
if (closeConnection) {
Connection.Close();
Connection.Dispose();
}
Connection = null;
}
}
protected virtual void Dispose(bool disposing) {
if (disposing)
DoDispose(true);
}
void HandleNullReferenceException(Exception ex) {
if (ex == null) return;
if (ex is NullReferenceException && InnerDataStore.Connection.State == ConnectionState.Open) {
DoReconnect();
return;
}
NpgsqlException npgex = ex as NpgsqlException;
if (npgex != null && npgex.Errors != null && InnerDataStore.Connection.State == ConnectionState.Open) {
foreach (NpgsqlError error in npgex.Errors) {
if (error.Message.Contains("broken")) {
DoReconnect();
return;
}
}
}
throw ex;
}
AutoCreateOption IDataStore.AutoCreateOption {
get { return InnerDataStore.AutoCreateOption; }
}
ModificationResult IDataStore.ModifyData(params ModificationStatement[] dmlStatements) {
try {
return InnerDataStore.ModifyData(dmlStatements);
} catch (SqlExecutionErrorException ex) {
HandleNullReferenceException(ex.InnerException);
}
return InnerDataStore.ModifyData(dmlStatements);
}
SelectedData IDataStore.SelectData(params SelectStatement[] selects) {
try {
return InnerDataStore.SelectData(selects);
} catch (NullReferenceException ex) {
HandleNullReferenceException(ex.InnerException);
}
return InnerDataStore.SelectData(selects);
}
UpdateSchemaResult IDataStore.UpdateSchema(bool dontCreateIfFirstTableNotExist, params DBTable[] tables) {
try {
return InnerDataStore.UpdateSchema(dontCreateIfFirstTableNotExist, tables);
} catch (SqlExecutionErrorException ex) {
HandleNullReferenceException(ex.InnerException);
}
return InnerDataStore.UpdateSchema(dontCreateIfFirstTableNotExist, tables);
}
void IDisposable.Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
//T270757
public object Do(string command, object args) {
return ((ICommandChannel)InnerDataStore).Do(command, args);
}
}
}