方便以后直接调用。
XpoInitializer.cs
using System;
using System.Configuration;
using System.Reflection;
using DevExpress.Xpo;
using DevExpress.Xpo.DB;
namespace XpoHelper
{
public static class XpoInitializer
{
/// <summary>
/// 调用XPO更新数据库结构。
/// 需要在具有相应权限的数据库帐户下运行。
/// </summary>
/// <param name="assemblies">整个项目中所有包含了XPO持久类的程序集。如:typeof(LibraryA.ClassA).Assembly, typeof(LibraryB.ClassB).Assembly...</param>
public static void UpdateDatabaseSchema(params Assembly[] assemblies)
{
string conn = GetConnectionString();
IDataLayer datalayer = XpoDefault.GetDataLayer(conn, AutoCreateOption.DatabaseAndSchema);
using (Session session = new Session(datalayer))
{
session.UpdateSchema(assemblies);
session.CreateObjectTypeRecords(assemblies);
}
}
/// <summary>
/// 根据配置文件创建并返回一个线程安全的XpoDataLayer。
/// 用在有多线程并发访问的场合,如ASP.NET项目。
/// 此方法同时会将该DataLayer指定给XpoDefault.DataLayer。
/// 并且将XpoDefault.Session置空。
/// </summary>
/// <param name="assemblies">整个项目中所有包含了XPO持久类的程序集。如:typeof(LibraryA.ClassA).Assembly, typeof(LibraryB.ClassB).Assembly...</param>
/// <returns>创建完成的ThreadSafeDataLayer</returns>
public static ThreadSafeDataLayer CreateThreadSafeDataLayer(params Assembly[] assemblies)
{
string conn = GetConnectionString();
DevExpress.Xpo.Metadata.XPDictionary dict = new DevExpress.Xpo.Metadata.ReflectionDictionary();
IDataStore store = XpoDefault.GetConnectionProvider(conn, AutoCreateOption.SchemaAlreadyExists);
dict.GetDataStoreSchema(assemblies);
ThreadSafeDataLayer datalayer = new ThreadSafeDataLayer(dict, store);
XpoDefault.DataLayer = datalayer;
XpoDefault.Session = null;
return datalayer;
}
/// <summary>
/// 尝试根据配置文件中在appSettings节下指定的设置构造数据库连接字符串。
/// 若失败则尝试获取connectionStrings节下指定的第一个连接字符串。
/// </summary>
/// <returns>构造或获取到的数据库连接字符串</returns>
public static string GetConnectionString()
{
try
{
AppSettingsReader config = new AppSettingsReader();
string serverType, server, database, user, password;
serverType = ((string)(config.GetValue("ServerType", typeof(string))));
server = ((string)(config.GetValue("Server", typeof(string))));
database = ((string)(config.GetValue("Database", typeof(string))));
user = ((string)(config.GetValue("User", typeof(string))));
password = ((string)(config.GetValue("Password", typeof(string))));
switch (serverType.ToUpper())
{
case "ACCESS":
return AccessConnectionProvider.GetConnectionString(database, user, password);
case "MSSQL":
return MSSqlConnectionProvider.GetConnectionString(server, user, password, database);
case "MYSQL":
return MySqlConnectionProvider.GetConnectionString(server, user, password, database);
case "ORACLE":
return OracleConnectionProvider.GetConnectionString(server, user, password);
// ... generate connection strings for other providers, e.g. Firebird, etc.
default:
return ConfigurationManager.ConnectionStrings[0].ToString();
}
}
catch
{
return ConfigurationManager.ConnectionStrings[0].ToString();
}
}
}
}
using System.Configuration;
using System.Reflection;
using DevExpress.Xpo;
using DevExpress.Xpo.DB;
namespace XpoHelper
{
public static class XpoInitializer
{
/// <summary>
/// 调用XPO更新数据库结构。
/// 需要在具有相应权限的数据库帐户下运行。
/// </summary>
/// <param name="assemblies">整个项目中所有包含了XPO持久类的程序集。如:typeof(LibraryA.ClassA).Assembly, typeof(LibraryB.ClassB).Assembly...</param>
public static void UpdateDatabaseSchema(params Assembly[] assemblies)
{
string conn = GetConnectionString();
IDataLayer datalayer = XpoDefault.GetDataLayer(conn, AutoCreateOption.DatabaseAndSchema);
using (Session session = new Session(datalayer))
{
session.UpdateSchema(assemblies);
session.CreateObjectTypeRecords(assemblies);
}
}
/// <summary>
/// 根据配置文件创建并返回一个线程安全的XpoDataLayer。
/// 用在有多线程并发访问的场合,如ASP.NET项目。
/// 此方法同时会将该DataLayer指定给XpoDefault.DataLayer。
/// 并且将XpoDefault.Session置空。
/// </summary>
/// <param name="assemblies">整个项目中所有包含了XPO持久类的程序集。如:typeof(LibraryA.ClassA).Assembly, typeof(LibraryB.ClassB).Assembly...</param>
/// <returns>创建完成的ThreadSafeDataLayer</returns>
public static ThreadSafeDataLayer CreateThreadSafeDataLayer(params Assembly[] assemblies)
{
string conn = GetConnectionString();
DevExpress.Xpo.Metadata.XPDictionary dict = new DevExpress.Xpo.Metadata.ReflectionDictionary();
IDataStore store = XpoDefault.GetConnectionProvider(conn, AutoCreateOption.SchemaAlreadyExists);
dict.GetDataStoreSchema(assemblies);
ThreadSafeDataLayer datalayer = new ThreadSafeDataLayer(dict, store);
XpoDefault.DataLayer = datalayer;
XpoDefault.Session = null;
return datalayer;
}
/// <summary>
/// 尝试根据配置文件中在appSettings节下指定的设置构造数据库连接字符串。
/// 若失败则尝试获取connectionStrings节下指定的第一个连接字符串。
/// </summary>
/// <returns>构造或获取到的数据库连接字符串</returns>
public static string GetConnectionString()
{
try
{
AppSettingsReader config = new AppSettingsReader();
string serverType, server, database, user, password;
serverType = ((string)(config.GetValue("ServerType", typeof(string))));
server = ((string)(config.GetValue("Server", typeof(string))));
database = ((string)(config.GetValue("Database", typeof(string))));
user = ((string)(config.GetValue("User", typeof(string))));
password = ((string)(config.GetValue("Password", typeof(string))));
switch (serverType.ToUpper())
{
case "ACCESS":
return AccessConnectionProvider.GetConnectionString(database, user, password);
case "MSSQL":
return MSSqlConnectionProvider.GetConnectionString(server, user, password, database);
case "MYSQL":
return MySqlConnectionProvider.GetConnectionString(server, user, password, database);
case "ORACLE":
return OracleConnectionProvider.GetConnectionString(server, user, password);
// ... generate connection strings for other providers, e.g. Firebird, etc.
default:
return ConfigurationManager.ConnectionStrings[0].ToString();
}
}
catch
{
return ConfigurationManager.ConnectionStrings[0].ToString();
}
}
}
}
使用的方法很简单:
Global.asax.cs
using System;
using DevExpress.Xpo;
namespace Test
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
// 更新数据库结构
// 因为需要较高的数据库帐户权限
// 出于安全性考虑的话,可以另起一个项目
// 分配一个较高权限的数据库帐户用以执行此操作
XpoHelper.XpoInitializer.UpdateDatabaseSchema(typeof(Model.SomeClass).Assembly);
// 创建并获取一个线程安全的XpoDataLayer
IDataLayer dataLayer = XpoHelper.XpoInitializer.CreateThreadSafeDataLayer(typeof(Model.SomeClass).Assembly);
// 上句代码执行完毕以后,新建的ThreadSafeDataLayer已经被指定给XpoDefault.DataLayer。
// 若有需要也可以另行保存一份,便于后续调用。
Application.Add("XpoLayer", dataLayer);
}
}
}
using DevExpress.Xpo;
namespace Test
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
// 更新数据库结构
// 因为需要较高的数据库帐户权限
// 出于安全性考虑的话,可以另起一个项目
// 分配一个较高权限的数据库帐户用以执行此操作
XpoHelper.XpoInitializer.UpdateDatabaseSchema(typeof(Model.SomeClass).Assembly);
// 创建并获取一个线程安全的XpoDataLayer
IDataLayer dataLayer = XpoHelper.XpoInitializer.CreateThreadSafeDataLayer(typeof(Model.SomeClass).Assembly);
// 上句代码执行完毕以后,新建的ThreadSafeDataLayer已经被指定给XpoDefault.DataLayer。
// 若有需要也可以另行保存一份,便于后续调用。
Application.Add("XpoLayer", dataLayer);
}
}
}
配置文件中对数据库连接字符串的指定需要注意。
我们虽然可以像普通项目那样,直接在config文件中写好connectionstring,由XPO尝试根据该连接字符串去连接数据库并且判断出数据库的类型。然而这样做并不是十分的稳妥(有可能猜错>.<)。 比较好的办法是我们显式的指定数据库类型,帐号等信息,由XPO自己构建出连接字符串。
web.config
<appSettings>
<!-- Configuration for database-->
<add key="ServerType" value="ACCESS"/>
<add key="Server" value=""/>
<add key="Database" value="D:\test.mdb"/>
<add key="User" value=""/>
<add key="Password" value=""/>
<!--<add key="ServerType" value="MSSQL"/>
<add key="Server" value="127.0.0.10"/>
<add key="Database" value="Test"/>
<add key="User" value="sa"/>
<add key="Password" value="sa"/>-->
<!--<add key="ServerType" value="MySQL" />
<add key="Server" value="127.0.0.1" />
<add key="Database" value="Test" />
<add key="User" value="root" />
<add key="Password" value="sa" />-->
</appSettings>
<connectionStrings/>
<!-- Configuration for database-->
<add key="ServerType" value="ACCESS"/>
<add key="Server" value=""/>
<add key="Database" value="D:\test.mdb"/>
<add key="User" value=""/>
<add key="Password" value=""/>
<!--<add key="ServerType" value="MSSQL"/>
<add key="Server" value="127.0.0.10"/>
<add key="Database" value="Test"/>
<add key="User" value="sa"/>
<add key="Password" value="sa"/>-->
<!--<add key="ServerType" value="MySQL" />
<add key="Server" value="127.0.0.1" />
<add key="Database" value="Test" />
<add key="User" value="root" />
<add key="Password" value="sa" />-->
</appSettings>
<connectionStrings/>