之前写过一个XPO初始化类,刚学了个DataStoreFork,改造了一下:
1 using System.Configuration;
2 using System.Reflection;
3 using DevExpress.Xpo;
4 using DevExpress.Xpo.DB;
5 using DevExpress.Xpo.Metadata;
6
7 namespace XpoHelper
8 {
9 public static class XpoInitializer
10 {
11 /// <summary>
12 /// 调用XPO更新数据库结构。
13 /// 需要在具有相应权限的数据库帐户下运行。
14 /// </summary>
15 /// <param name="assemblies">整个项目中所有包含了XPO持久类的程序集。如:typeof(LibraryA.ClassA).Assembly, typeof(LibraryB.ClassB).Assembly...</param>
16 public static void UpdateDatabaseSchema(params Assembly[] assemblies)
17 {
18 string conn = GetConnectionString();
19 IDataLayer datalayer = XpoDefault.GetDataLayer(conn, AutoCreateOption.DatabaseAndSchema);
20 using (Session session = new Session(datalayer))
21 {
22 session.UpdateSchema(assemblies);
23 session.CreateObjectTypeRecords(assemblies);
24 }
25 }
26
27 /// <summary>
28 /// 根据配置文件创建并返回一个线程安全的XpoDataLayer。
29 /// 用在有多线程并发访问的场合,如ASP.NET项目。
30 /// 此方法同时会将该DataLayer指定给XpoDefault.DataLayer。
31 /// 并且将XpoDefault.Session置空。
32 /// </summary>
33 /// <param name="assemblies">整个项目中所有包含了XPO持久类的程序集。如:typeof(LibraryA.ClassA).Assembly, typeof(LibraryB.ClassB).Assembly...</param>
34 /// <returns>创建完成的ThreadSafeDataLayer</returns>
35 public static IDataLayer CreateThreadSafeDataLayer(params Assembly[] assemblies)
36 {
37 IDataLayer datalayer = GetDataLayer(assemblies);
38
39 XpoDefault.DataLayer = datalayer;
40
41 XpoDefault.Session = null;
42
43 return datalayer;
44 }
45
46 /// <summary>
47 /// 根据连接字符串创建 XPO 的 DataStore
48 /// </summary>
49 /// <returns></returns>
50 static IDataStore GetDataStore()
51 {
52 string conn = GetConnectionString();
53
54 IDataStore store = XpoDefault.GetConnectionProvider(conn, AutoCreateOption.SchemaAlreadyExists);
55
56 return store;
57 }
58
59 /// <summary>
60 /// 创建 XPO 的 ThreadSafeDataLayer
61 /// </summary>
62 /// <param name="assemblies"></param>
63 /// <returns></returns>
64 static IDataLayer GetDataLayer(params Assembly[] assemblies)
65 {
66 ReflectionDictionary dict = new ReflectionDictionary();
67 dict.CollectClassInfos(assemblies);
68
69 IDataLayer dataLayer;
70
71 int maxConnections = GetMaxConnections();
72
73 if (maxConnections > 1)
74 {
75 IDataStore[] stores = new IDataStore[maxConnections];
76 for (int i = 0; i < maxConnections; i++)
77 stores[i] = GetDataStore();
78 dataLayer = new ThreadSafeDataLayer(dict, new DataStoreFork(stores));
79 }
80 else
81 {
82 dataLayer = new ThreadSafeDataLayer(dict, GetDataStore());
83 }
84
85 return dataLayer;
86 }
87
88 /// <summary>
89 /// 根据配置节获取XPO数据库最大并发连接数
90 /// </summary>
91 /// <returns>若配置节存在,返回配置节设置值,否则返回 1</returns>
92 static int GetMaxConnections()
93 {
94 AppSettingsReader config = new AppSettingsReader();
95 int conns;
96
97 try
98 {
99 conns = (int)config.GetValue("DatabaseMaxConnections", typeof(int));
100 }
101 catch
102 {
103 conns = 1;
104 }
105 return conns;
106 }
107
108 /// <summary>
109 /// 尝试根据配置文件中在appSettings节下指定的设置构造数据库连接字符串。
110 /// 若失败则尝试获取connectionStrings节下指定的第一个连接字符串。
111 /// </summary>
112 /// <returns>构造或获取到的数据库连接字符串</returns>
113 public static string GetConnectionString()
114 {
115 try
116 {
117 AppSettingsReader config = new AppSettingsReader();
118 string serverType, server, database, user, password;
119 serverType = ((string)(config.GetValue("ServerType", typeof(string))));
120 server = ((string)(config.GetValue("Server", typeof(string))));
121 database = ((string)(config.GetValue("Database", typeof(string))));
122 user = ((string)(config.GetValue("User", typeof(string))));
123 password = ((string)(config.GetValue("Password", typeof(string))));
124 switch (serverType.ToUpper())
125 {
126 case "ACCESS":
127 return AccessConnectionProvider.GetConnectionString(database, user, password);
128 case "MSSQL":
129 return MSSqlConnectionProvider.GetConnectionString(server, user, password, database);
130 case "MYSQL":
131 return MySqlConnectionProvider.GetConnectionString(server, user, password, database);
132 case "ORACLE":
133 return OracleConnectionProvider.GetConnectionString(server, user, password);
134 // ... generate connection strings for other providers, e.g. Firebird, etc.
135 default:
136 return ConfigurationManager.ConnectionStrings[0].ToString();
137 }
138 }
139 catch
140 {
141 return ConfigurationManager.ConnectionStrings[0].ToString();
142 }
143 }
144 }
145 }
2 using System.Reflection;
3 using DevExpress.Xpo;
4 using DevExpress.Xpo.DB;
5 using DevExpress.Xpo.Metadata;
6
7 namespace XpoHelper
8 {
9 public static class XpoInitializer
10 {
11 /// <summary>
12 /// 调用XPO更新数据库结构。
13 /// 需要在具有相应权限的数据库帐户下运行。
14 /// </summary>
15 /// <param name="assemblies">整个项目中所有包含了XPO持久类的程序集。如:typeof(LibraryA.ClassA).Assembly, typeof(LibraryB.ClassB).Assembly...</param>
16 public static void UpdateDatabaseSchema(params Assembly[] assemblies)
17 {
18 string conn = GetConnectionString();
19 IDataLayer datalayer = XpoDefault.GetDataLayer(conn, AutoCreateOption.DatabaseAndSchema);
20 using (Session session = new Session(datalayer))
21 {
22 session.UpdateSchema(assemblies);
23 session.CreateObjectTypeRecords(assemblies);
24 }
25 }
26
27 /// <summary>
28 /// 根据配置文件创建并返回一个线程安全的XpoDataLayer。
29 /// 用在有多线程并发访问的场合,如ASP.NET项目。
30 /// 此方法同时会将该DataLayer指定给XpoDefault.DataLayer。
31 /// 并且将XpoDefault.Session置空。
32 /// </summary>
33 /// <param name="assemblies">整个项目中所有包含了XPO持久类的程序集。如:typeof(LibraryA.ClassA).Assembly, typeof(LibraryB.ClassB).Assembly...</param>
34 /// <returns>创建完成的ThreadSafeDataLayer</returns>
35 public static IDataLayer CreateThreadSafeDataLayer(params Assembly[] assemblies)
36 {
37 IDataLayer datalayer = GetDataLayer(assemblies);
38
39 XpoDefault.DataLayer = datalayer;
40
41 XpoDefault.Session = null;
42
43 return datalayer;
44 }
45
46 /// <summary>
47 /// 根据连接字符串创建 XPO 的 DataStore
48 /// </summary>
49 /// <returns></returns>
50 static IDataStore GetDataStore()
51 {
52 string conn = GetConnectionString();
53
54 IDataStore store = XpoDefault.GetConnectionProvider(conn, AutoCreateOption.SchemaAlreadyExists);
55
56 return store;
57 }
58
59 /// <summary>
60 /// 创建 XPO 的 ThreadSafeDataLayer
61 /// </summary>
62 /// <param name="assemblies"></param>
63 /// <returns></returns>
64 static IDataLayer GetDataLayer(params Assembly[] assemblies)
65 {
66 ReflectionDictionary dict = new ReflectionDictionary();
67 dict.CollectClassInfos(assemblies);
68
69 IDataLayer dataLayer;
70
71 int maxConnections = GetMaxConnections();
72
73 if (maxConnections > 1)
74 {
75 IDataStore[] stores = new IDataStore[maxConnections];
76 for (int i = 0; i < maxConnections; i++)
77 stores[i] = GetDataStore();
78 dataLayer = new ThreadSafeDataLayer(dict, new DataStoreFork(stores));
79 }
80 else
81 {
82 dataLayer = new ThreadSafeDataLayer(dict, GetDataStore());
83 }
84
85 return dataLayer;
86 }
87
88 /// <summary>
89 /// 根据配置节获取XPO数据库最大并发连接数
90 /// </summary>
91 /// <returns>若配置节存在,返回配置节设置值,否则返回 1</returns>
92 static int GetMaxConnections()
93 {
94 AppSettingsReader config = new AppSettingsReader();
95 int conns;
96
97 try
98 {
99 conns = (int)config.GetValue("DatabaseMaxConnections", typeof(int));
100 }
101 catch
102 {
103 conns = 1;
104 }
105 return conns;
106 }
107
108 /// <summary>
109 /// 尝试根据配置文件中在appSettings节下指定的设置构造数据库连接字符串。
110 /// 若失败则尝试获取connectionStrings节下指定的第一个连接字符串。
111 /// </summary>
112 /// <returns>构造或获取到的数据库连接字符串</returns>
113 public static string GetConnectionString()
114 {
115 try
116 {
117 AppSettingsReader config = new AppSettingsReader();
118 string serverType, server, database, user, password;
119 serverType = ((string)(config.GetValue("ServerType", typeof(string))));
120 server = ((string)(config.GetValue("Server", typeof(string))));
121 database = ((string)(config.GetValue("Database", typeof(string))));
122 user = ((string)(config.GetValue("User", typeof(string))));
123 password = ((string)(config.GetValue("Password", typeof(string))));
124 switch (serverType.ToUpper())
125 {
126 case "ACCESS":
127 return AccessConnectionProvider.GetConnectionString(database, user, password);
128 case "MSSQL":
129 return MSSqlConnectionProvider.GetConnectionString(server, user, password, database);
130 case "MYSQL":
131 return MySqlConnectionProvider.GetConnectionString(server, user, password, database);
132 case "ORACLE":
133 return OracleConnectionProvider.GetConnectionString(server, user, password);
134 // ... generate connection strings for other providers, e.g. Firebird, etc.
135 default:
136 return ConfigurationManager.ConnectionStrings[0].ToString();
137 }
138 }
139 catch
140 {
141 return ConfigurationManager.ConnectionStrings[0].ToString();
142 }
143 }
144 }
145 }
用法和之前的一样,注意在Config文件的AppSetting节里要增加一条:
<add key="DatabaseMaxConnections" value="2"/>
Value应该>=1,<=数据库服务器的CPU核心数。
如果没有这一节,或者Value<=1,则不会使用DataStoreFork,仍然使用以前的方法创建XPODataLayer。