PageRenderTime 37ms CodeModel.GetById 8ms RepoModel.GetById 1ms app.codeStats 0ms

/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Table.cs

https://bitbucket.org/danipen/mono
C# | 368 lines | 224 code | 53 blank | 91 comment | 10 complexity | d922b5482c86b23809ca11c058dddb7f MD5 | raw file
Possible License(s): Unlicense, Apache-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
  1. #region MIT license
  2. //
  3. // MIT license
  4. //
  5. // Copyright (c) 2007-2008 Jiri Moudry, Pascal Craponne
  6. //
  7. // Permission is hereby granted, free of charge, to any person obtaining a copy
  8. // of this software and associated documentation files (the "Software"), to deal
  9. // in the Software without restriction, including without limitation the rights
  10. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. // copies of the Software, and to permit persons to whom the Software is
  12. // furnished to do so, subject to the following conditions:
  13. //
  14. // The above copyright notice and this permission notice shall be included in
  15. // all copies or substantial portions of the Software.
  16. //
  17. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. // THE SOFTWARE.
  24. //
  25. #endregion
  26. using System;
  27. using System.Data;
  28. using System.Data.Linq;
  29. using System.Reflection;
  30. using System.Diagnostics;
  31. using System.Collections;
  32. using System.Collections.Generic;
  33. using System.Linq;
  34. using System.Linq.Expressions;
  35. using System.ComponentModel;
  36. #if MONO_STRICT
  37. using ITable = System.Data.Linq.ITable;
  38. #else
  39. using ITable = DbLinq.Data.Linq.ITable;
  40. #endif
  41. using DbLinq;
  42. using DbLinq.Data.Linq.Implementation;
  43. using DbLinq.Data.Linq.Sugar;
  44. #if MONO_STRICT
  45. namespace System.Data.Linq
  46. #else
  47. namespace DbLinq.Data.Linq
  48. #endif
  49. {
  50. /// <summary>
  51. /// T may be eg. class Employee or string - the output
  52. /// </summary>
  53. /// <typeparam name="TEntity">The type of the entity.</typeparam>
  54. public sealed partial class Table<TEntity> :
  55. ITable,
  56. IQueryProvider,
  57. IListSource,
  58. IEnumerable<TEntity>,
  59. IEnumerable,
  60. IQueryable<TEntity>,
  61. IQueryable
  62. where TEntity : class
  63. {
  64. /// <summary>
  65. /// the parent DataContext holds our connection etc
  66. /// </summary>
  67. public DataContext Context { get; private set; }
  68. // QueryProvider is the running entity, running through nested Expressions
  69. private readonly QueryProvider<TEntity> _queryProvider;
  70. /// <summary>
  71. /// Initializes a new instance of the <see cref="Table&lt;TEntity&gt;"/> class.
  72. /// </summary>
  73. /// <param name="parentContext">The parent context.</param>
  74. internal Table(DataContext parentContext)
  75. {
  76. Context = parentContext;
  77. _queryProvider = new QueryProvider<TEntity>(parentContext);
  78. }
  79. /// <summary>
  80. /// 'S' is the projected type. If you say 'from e in Employees select e.ID', then type S will be int.
  81. /// If you say 'select new {e.ID}', then type S will be something like Projection.f__1
  82. /// </summary>
  83. IQueryable<S> IQueryProvider.CreateQuery<S>(Expression expr)
  84. {
  85. return _queryProvider.CreateQuery<S>(expr);
  86. }
  87. /// <summary>
  88. /// this is only called during Dynamic Linq
  89. /// </summary>
  90. IQueryable IQueryProvider.CreateQuery(Expression expression)
  91. {
  92. return _queryProvider.CreateQuery(expression);
  93. }
  94. /// <summary>
  95. /// the query '(from o in Orders select o).First()' enters here
  96. /// </summary>
  97. S IQueryProvider.Execute<S>(Expression expression)
  98. {
  99. return _queryProvider.Execute<S>(expression);
  100. }
  101. /// <summary>
  102. /// Executes the current expression
  103. /// </summary>
  104. /// <param name="expression"></param>
  105. /// <returns></returns>
  106. object IQueryProvider.Execute(Expression expression)
  107. {
  108. return _queryProvider.Execute(expression);
  109. }
  110. /// <summary>
  111. /// entry point for 'foreach' statement.
  112. /// </summary>
  113. public IEnumerator<TEntity> GetEnumerator()
  114. {
  115. var queryable = this as IQueryable<TEntity>;
  116. var query = queryable.Select(t => t);
  117. return query.GetEnumerator();
  118. }
  119. IEnumerator<TEntity> IEnumerable<TEntity>.GetEnumerator()
  120. {
  121. return GetEnumerator();
  122. }
  123. /// <summary>
  124. /// Enumerates all table items
  125. /// </summary>
  126. /// <returns></returns>
  127. IEnumerator IEnumerable.GetEnumerator()
  128. {
  129. return GetEnumerator();
  130. }
  131. Type IQueryable.ElementType
  132. {
  133. get { return _queryProvider.ElementType; }
  134. }
  135. /// <summary>
  136. /// Returns this table as an Expression
  137. /// </summary>
  138. Expression IQueryable.Expression
  139. {
  140. get { return Expression.Constant(this); } // do not change this to _queryProvider.Expression, Sugar doesn't fully handle QueryProviders by now
  141. }
  142. /// <summary>
  143. /// IQueryable.Provider: represents the Table as a IQueryable provider (hence the name)
  144. /// </summary>
  145. IQueryProvider IQueryable.Provider
  146. {
  147. get { return _queryProvider.Provider; }
  148. }
  149. #region Insert functions
  150. void ITable.InsertOnSubmit(object entity)
  151. {
  152. Context.RegisterInsert(entity);
  153. }
  154. public void InsertOnSubmit(TEntity entity)
  155. {
  156. Context.RegisterInsert(entity);
  157. }
  158. void ITable.InsertAllOnSubmit(IEnumerable entities)
  159. {
  160. foreach (var entity in entities)
  161. Context.RegisterInsert(entity);
  162. }
  163. public void InsertAllOnSubmit<TSubEntity>(IEnumerable<TSubEntity> entities) where TSubEntity : TEntity
  164. {
  165. if (entities == null)
  166. throw new ArgumentNullException("entities");
  167. foreach (var entity in entities)
  168. Context.RegisterInsert(entity);
  169. }
  170. #endregion
  171. #region Delete functions
  172. void ITable.DeleteAllOnSubmit(IEnumerable entities)
  173. {
  174. foreach (var entity in entities)
  175. Context.RegisterDelete(entity);
  176. }
  177. /// <summary>
  178. /// required by ITable interface
  179. /// </summary>
  180. /// <param name="entity"></param>
  181. void ITable.DeleteOnSubmit(object entity)
  182. {
  183. Context.RegisterDelete(entity);
  184. }
  185. public void DeleteOnSubmit(TEntity entity)
  186. {
  187. Context.RegisterDelete(entity);
  188. }
  189. public void DeleteAllOnSubmit<TSubEntity>(IEnumerable<TSubEntity> entities) where TSubEntity : TEntity
  190. {
  191. if (entities == null)
  192. throw new ArgumentNullException("entities");
  193. foreach (var row in entities)
  194. Context.RegisterDelete(row);
  195. }
  196. #endregion
  197. #region Attach functions
  198. /// <summary>
  199. /// required for ITable
  200. /// </summary>
  201. /// <param name="entity"></param>
  202. void ITable.Attach(object entity)
  203. {
  204. Context.RegisterUpdate(entity);
  205. }
  206. void ITable.Attach(object entity, object original)
  207. {
  208. Context.RegisterUpdate(entity, original);
  209. }
  210. void ITable.Attach(object entity, bool asModified)
  211. {
  212. Context.RegisterUpdate(entity, asModified ? null : entity);
  213. }
  214. void ITable.AttachAll(IEnumerable entities)
  215. {
  216. foreach (var entity in entities)
  217. Context.RegisterUpdate(entity);
  218. }
  219. void ITable.AttachAll(IEnumerable entities, bool asModified)
  220. {
  221. foreach (var entity in entities)
  222. Context.RegisterUpdate(entity, asModified ? null : entity);
  223. }
  224. /// <summary>
  225. /// Attaches an entity from another Context to a table,
  226. /// with the intention to perform an update or delete operation
  227. /// </summary>
  228. /// <param name="entity">table row object to attach</param>
  229. public void Attach(TEntity entity)
  230. {
  231. Context.RegisterUpdate(entity);
  232. }
  233. [DbLinqToDo]
  234. public void Attach(TEntity entity, bool asModified)
  235. {
  236. throw new NotImplementedException();
  237. }
  238. public void AttachAll<TSubEntity>(IEnumerable<TSubEntity> entities) where TSubEntity : TEntity
  239. {
  240. if (entities == null)
  241. throw new ArgumentNullException("entities");
  242. foreach (var entity in entities)
  243. Context.RegisterUpdate(entity);
  244. }
  245. [DbLinqToDo]
  246. public void AttachAll<TSubEntity>(IEnumerable<TSubEntity> entities, bool asModified) where TSubEntity : TEntity
  247. {
  248. throw new NotImplementedException();
  249. }
  250. /// <summary>
  251. /// Attaches existing entity with original state
  252. /// </summary>
  253. /// <param name="entity">live entity added to change tracking</param>
  254. /// <param name="original">original unchanged property values</param>
  255. public void Attach(TEntity entity, TEntity original)
  256. {
  257. Context.RegisterUpdate(entity, original);
  258. }
  259. #endregion
  260. /// <summary>
  261. /// Gets a value indicating whether this instance is read only.
  262. /// </summary>
  263. /// <value>
  264. /// <c>true</c> if this instance is read only; otherwise, <c>false</c>.
  265. /// </value>
  266. public bool IsReadOnly { get { return false; } }
  267. // PC: this will probably required to recreate a new object instance with all original values
  268. // (that we currently do not always store, so we may need to make a differential copy
  269. [Obsolete("NOT IMPLEMENTED YET")]
  270. [DbLinqToDo]
  271. ModifiedMemberInfo[] ITable.GetModifiedMembers(object entity)
  272. {
  273. throw new ApplicationException("L579 Not implemented");
  274. }
  275. // PC: complementary to GetModifiedMembers(), we probably need a few changes to the IMemberModificationHandler,
  276. // to recall original values
  277. [Obsolete("NOT IMPLEMENTED YET")]
  278. [DbLinqToDo]
  279. object ITable.GetOriginalEntityState(object entity)
  280. {
  281. throw new ApplicationException("L585 Not implemented");
  282. }
  283. bool IListSource.ContainsListCollection
  284. {
  285. get { return true; }
  286. }
  287. IList IListSource.GetList()
  288. {
  289. return this.ToList();
  290. }
  291. [DbLinqToDo]
  292. public TEntity GetOriginalEntityState(TEntity entity)
  293. {
  294. if (entity == null)
  295. throw new ArgumentNullException("entity");
  296. throw new NotImplementedException();
  297. }
  298. [DbLinqToDo]
  299. public IBindingList GetNewBindingList()
  300. {
  301. throw new NotImplementedException();
  302. }
  303. [DbLinqToDo]
  304. public ModifiedMemberInfo[] GetModifiedMembers(TEntity entity)
  305. {
  306. if (entity == null)
  307. throw new ArgumentNullException("entity");
  308. throw new NotImplementedException();
  309. }
  310. public override string ToString()
  311. {
  312. return string.Format("Table({0})", typeof(TEntity).Name);
  313. }
  314. }
  315. }