Line data Source code
1 : #region Copyright
2 : // // -----------------------------------------------------------------------
3 : // // <copyright company="cdmdotnet Limited">
4 : // // Copyright cdmdotnet Limited. All rights reserved.
5 : // // </copyright>
6 : // // -----------------------------------------------------------------------
7 : #endregion
8 :
9 : using System;
10 : using System.Collections;
11 : using System.Collections.Generic;
12 : using System.Data.Linq;
13 : using System.Linq;
14 : using System.Linq.Expressions;
15 : using cdmdotnet.Logging;
16 : using Cqrs.Configuration;
17 : using Cqrs.Entities;
18 :
19 : namespace Cqrs.DataStores
20 : {
21 : public class SqlDataStore<TData> : IDataStore<TData>
22 : where TData : Entity
23 0 : {
24 : internal const string SqlDataStoreDbFileOrServerOrConnectionApplicationKey = @"SqlDataStoreDbFileOrServerOrConnection";
25 :
26 : internal const string SqlDataStoreConnectionNameApplicationKey = @"Cqrs.SqlDataStore.ConnectionStringName";
27 :
28 : protected IConfigurationManager ConfigurationManager { get; private set; }
29 :
30 0 : public SqlDataStore(IConfigurationManager configurationManager, ILogger logger)
31 : {
32 : ConfigurationManager = configurationManager;
33 : Logger = logger;
34 : // Use a connection string.
35 : DbDataContext = CreateDbDataContext();
36 :
37 : // Get a typed table to run queries.
38 : Table = DbDataContext.GetTable<TData>();
39 : }
40 :
41 : protected DataContext DbDataContext { get; private set; }
42 :
43 : protected Table<TData> Table { get; private set; }
44 :
45 : protected ILogger Logger { get; private set; }
46 :
47 0 : protected virtual DataContext CreateDbDataContext()
48 : {
49 : string connectionStringKey;
50 : string applicationKey;
51 : if (!ConfigurationManager.TryGetSetting(SqlDataStoreConnectionNameApplicationKey, out applicationKey) || string.IsNullOrEmpty(applicationKey))
52 : {
53 : if (!ConfigurationManager.TryGetSetting(SqlDataStoreDbFileOrServerOrConnectionApplicationKey, out connectionStringKey) || string.IsNullOrEmpty(connectionStringKey))
54 : {
55 : throw new NullReferenceException(string.Format("No application setting named '{0}' was found in the configuration file with the name of a connection string to look for.", SqlDataStoreConnectionNameApplicationKey));
56 : }
57 : }
58 : else
59 : {
60 : try
61 : {
62 : connectionStringKey = System.Configuration.ConfigurationManager.ConnectionStrings[applicationKey].ConnectionString;
63 : }
64 : catch (NullReferenceException exception)
65 : {
66 : throw new NullReferenceException(string.Format("No connection string setting named '{0}' was found in the configuration file with the SQL Data Store connection string.", applicationKey), exception);
67 : }
68 : }
69 : return new DataContext(connectionStringKey);
70 : }
71 :
72 : #region Implementation of IEnumerable
73 :
74 : /// <summary>
75 : /// Returns an enumerator that iterates through the collection.
76 : /// </summary>
77 : /// <returns>
78 : /// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
79 : /// </returns>
80 1 : public IEnumerator<TData> GetEnumerator()
81 : {
82 : return Table.AsQueryable().GetEnumerator();
83 : }
84 :
85 : /// <summary>
86 : /// Returns an enumerator that iterates through a collection.
87 : /// </summary>
88 : /// <returns>
89 : /// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.
90 : /// </returns>
91 : IEnumerator IEnumerable.GetEnumerator()
92 : {
93 : return GetEnumerator();
94 : }
95 :
96 : #endregion
97 :
98 : #region Implementation of IQueryable
99 :
100 : /// <summary>
101 : /// Gets the expression tree that is associated with the instance of <see cref="T:System.Linq.IQueryable"/>.
102 : /// </summary>
103 : /// <returns>
104 : /// The <see cref="T:System.Linq.Expressions.Expression"/> that is associated with this instance of <see cref="T:System.Linq.IQueryable"/>.
105 : /// </returns>
106 : public Expression Expression
107 : {
108 : get { return Table.AsQueryable().Expression; }
109 : }
110 :
111 : /// <summary>
112 : /// Gets the type of the element(s) that are returned when the expression tree associated with this instance of <see cref="T:System.Linq.IQueryable"/> is executed.
113 : /// </summary>
114 : /// <returns>
115 : /// A <see cref="T:System.Type"/> that represents the type of the element(s) that are returned when the expression tree associated with this object is executed.
116 : /// </returns>
117 : public Type ElementType
118 : {
119 : get { return Table.AsQueryable().ElementType; }
120 : }
121 :
122 : /// <summary>
123 : /// Gets the query provider that is associated with this data source.
124 : /// </summary>
125 : /// <returns>
126 : /// The <see cref="T:System.Linq.IQueryProvider"/> that is associated with this data source.
127 : /// </returns>
128 : public IQueryProvider Provider
129 : {
130 : get { return Table.AsQueryable().Provider; }
131 : }
132 :
133 : #endregion
134 :
135 : #region Implementation of IDisposable
136 :
137 : /// <summary>
138 : /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
139 : /// </summary>
140 1 : public void Dispose()
141 : {
142 : Table = null;
143 : DbDataContext.Dispose();
144 : DbDataContext = null;
145 : }
146 :
147 : #endregion
148 :
149 : #region Implementation of IDataStore<TData>
150 :
151 0 : public virtual void Add(TData data)
152 : {
153 : Logger.LogDebug("Adding data to the Sql database", "SqlDataStore\\Add");
154 : try
155 : {
156 : DateTime start = DateTime.Now;
157 : Table.InsertOnSubmit(data);
158 : DbDataContext.SubmitChanges();
159 : DateTime end = DateTime.Now;
160 : Logger.LogDebug(string.Format("Adding data in the Sql database took {0}.", end - start), "SqlDataStore\\Add");
161 : }
162 : finally
163 : {
164 : Logger.LogDebug("Adding data to the Sql database... Done", "SqlDataStore\\Add");
165 : }
166 : }
167 :
168 0 : public virtual void Add(IEnumerable<TData> data)
169 : {
170 : Logger.LogDebug("Adding data collection to the Sql database", "SqlDataStore\\Add\\Collection");
171 : try
172 : {
173 : DateTime start = DateTime.Now;
174 : Table.InsertAllOnSubmit(data);
175 : DbDataContext.SubmitChanges();
176 : DateTime end = DateTime.Now;
177 : Logger.LogDebug(string.Format("Adding data in the Sql database took {0}.", end - start), "SqlDataStore\\Add\\Collection");
178 : }
179 : finally
180 : {
181 : Logger.LogDebug("Adding data collection to the Sql database... Done", "SqlDataStore\\Add\\Collection");
182 : }
183 : }
184 :
185 : /// <summary>
186 : /// Will mark the <paramref name="data"/> as logically (or soft) by setting <see cref="Entity.IsLogicallyDeleted"/> to true
187 : /// </summary>
188 1 : public virtual void Remove(TData data)
189 : {
190 : Logger.LogDebug("Removing data from the Sql database", "SqlDataStore\\Remove");
191 : try
192 : {
193 : DateTime start = DateTime.Now;
194 : data.IsLogicallyDeleted = true;
195 : Update(data);
196 : DateTime end = DateTime.Now;
197 : Logger.LogDebug(string.Format("Removing data from the Sql database took {0}.", end - start), "SqlDataStore\\Remove");
198 : }
199 : finally
200 : {
201 : Logger.LogDebug("Removing data from the Sql database... Done", "SqlDataStore\\Remove");
202 : }
203 : }
204 :
205 0 : public void Destroy(TData data)
206 : {
207 : Logger.LogDebug("Removing data from the Sql database", "SqlDataStore\\Destroy");
208 : try
209 : {
210 : DateTime start = DateTime.Now;
211 : try
212 : {
213 : Table.DeleteOnSubmit(data);
214 : }
215 : catch (InvalidOperationException exception)
216 : {
217 : if (exception.Message != "Cannot remove an entity that has not been attached.")
218 : throw;
219 : Table.Attach(data);
220 : DbDataContext.Refresh(RefreshMode.KeepCurrentValues, data);
221 : Table.DeleteOnSubmit(data);
222 : }
223 : DbDataContext.SubmitChanges();
224 : DateTime end = DateTime.Now;
225 : Logger.LogDebug(string.Format("Removing data from the Sql database took {0}.", end - start), "SqlDataStore\\Destroy");
226 : }
227 : finally
228 : {
229 : Logger.LogDebug("Removing data from the Sql database... Done", "SqlDataStore\\Destroy");
230 : }
231 : }
232 :
233 0 : public virtual void RemoveAll()
234 : {
235 : Logger.LogDebug("Removing all from the Sql database", "SqlDataStore\\RemoveAll");
236 : try
237 : {
238 : Table.Truncate();
239 : }
240 : finally
241 : {
242 : Logger.LogDebug("Removing all from the Sql database... Done", "SqlDataStore\\RemoveAll");
243 : }
244 : }
245 :
246 0 : public virtual void Update(TData data)
247 : {
248 : Logger.LogDebug("Updating data in the Sql database", "SqlDataStore\\Update");
249 : try
250 : {
251 : DateTime start = DateTime.Now;
252 : Table.Attach(data);
253 : DbDataContext.Refresh(RefreshMode.KeepCurrentValues, data);
254 : DbDataContext.SubmitChanges();
255 : DateTime end = DateTime.Now;
256 : Logger.LogDebug(string.Format("Updating data in the Sql database took {0}.", end - start), "SqlDataStore\\Update");
257 : }
258 : finally
259 : {
260 : Logger.LogDebug("Updating data to the Sql database... Done", "SqlDataStore\\Update");
261 : }
262 : }
263 :
264 : #endregion
265 : }
266 : }
|