PageRenderTime 51ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/Tests/Test.WebApi2.EF6/Controllers/NorthwindIBModelController.cs

https://github.com/WilliamBZA/breeze.server.net
C# | 932 lines | 754 code | 136 blank | 42 comment | 107 complexity | 24044ff719a63800d6508a253b28df58 MD5 | raw file
  1. // Only one of the next 5 should be uncommented.
  2. #define CODEFIRST_PROVIDER
  3. //#define DATABASEFIRST_NEW
  4. //#define ORACLE_EDMX
  5. //#define NHIBERNATE
  6. using System;
  7. using System.Net;
  8. using System.Linq;
  9. using System.Runtime.InteropServices;
  10. using System.Web.Http;
  11. using Breeze.ContextProvider;
  12. using Breeze.WebApi2;
  13. using Microsoft.SqlServer.Server;
  14. using Newtonsoft.Json.Linq;
  15. using System.Collections.Generic;
  16. using System.Net.Http;
  17. using System.Net.Http.Headers;
  18. using System.Data.SqlClient;
  19. using System.IO;
  20. using System.Web;
  21. using NHibernate.Mapping;
  22. using NHibernate.Transform;
  23. #if CODEFIRST_PROVIDER
  24. using Breeze.ContextProvider.EF6;
  25. using Models.NorthwindIB.CF;
  26. using Foo;
  27. using System.ComponentModel.DataAnnotations;
  28. using System.Web.Http.OData.Query;
  29. #elif DATABASEFIRST_OLD
  30. using Breeze.ContextProvider.EF6;
  31. using Models.NorthwindIB.EDMX;
  32. #elif DATABASEFIRST_NEW
  33. using Breeze.ContextProvider.EF6;
  34. using Models.NorthwindIB.EDMX_2012;
  35. #elif ORACLE_EDMX
  36. using Breeze.ContextProvider.EF6;
  37. using Models.NorthwindIB.Oracle;
  38. #elif NHIBERNATE
  39. using Breeze.ContextProvider.NH;
  40. using NHibernate;
  41. using NHibernate.Linq;
  42. using Models.NorthwindIB.NH;
  43. #endif
  44. namespace Sample_WebApi2.Controllers {
  45. #if CODEFIRST_PROVIDER
  46. public class NorthwindContextProvider: EFContextProvider<NorthwindIBContext_CF> {
  47. public NorthwindContextProvider() : base() { }
  48. #elif DATABASEFIRST_OLD
  49. public class NorthwindContextProvider: EFContextProvider<NorthwindIBContext_EDMX> {
  50. public NorthwindContextProvider() : base() { }
  51. #elif DATABASEFIRST_NEW
  52. public class NorthwindContextProvider : EFContextProvider<NorthwindIBContext_EDMX_2012> {
  53. public NorthwindContextProvider() : base() { }
  54. #elif ORACLE_EDMX
  55. public class NorthwindContextProvider : EFContextProvider<NorthwindIBContext_EDMX_Oracle> {
  56. public NorthwindContextProvider() : base() { }
  57. #elif NHIBERNATE
  58. public class NorthwindContextProvider : NorthwindNHContext {
  59. #endif
  60. protected override void AfterSaveEntities(Dictionary<Type, List<EntityInfo>> saveMap, List<KeyMapping> keyMappings) {
  61. var tag = (string)SaveOptions.Tag;
  62. if (tag == "CommentKeyMappings.After") {
  63. foreach (var km in keyMappings) {
  64. var realint = Convert.ToInt32(km.RealValue);
  65. byte seq = (byte)(realint % 512);
  66. AddComment(km.EntityTypeName + ':' + km.RealValue, seq);
  67. }
  68. } else if (tag == "UpdateProduceKeyMapping.After") {
  69. if (!keyMappings.Any()) throw new Exception("UpdateProduce.After: No key mappings available");
  70. var km = keyMappings[0];
  71. UpdateProduceDescription(km.EntityTypeName + ':' + km.RealValue);
  72. } else if (tag == "LookupEmployeeInSeparateContext.After") {
  73. LookupEmployeeInSeparateContext(false);
  74. } else if (tag == "LookupEmployeeInSeparateContext.SameConnection.After") {
  75. LookupEmployeeInSeparateContext(true);
  76. }
  77. base.AfterSaveEntities(saveMap, keyMappings);
  78. }
  79. #if (CODEFIRST_PROVIDER || DATABASEFIRST_NEW || DATABASEFIRST_OLD)
  80. /* hack to set the current DbTransaction onto the DbCommand. Transaction comes from EF private properties. */
  81. public void SetCurrentTransaction(System.Data.Common.DbCommand command) {
  82. if (EntityTransaction != null) {
  83. // get private member via reflection
  84. var bindingFlags = System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Instance;
  85. var etype = EntityTransaction.GetType();
  86. var stProp = etype.GetProperty("StoreTransaction", bindingFlags);
  87. var transaction = stProp.GetValue(EntityTransaction, null);
  88. var dbTransaction = transaction as System.Data.Common.DbTransaction;
  89. if (dbTransaction != null) {
  90. command.Transaction = dbTransaction;
  91. }
  92. }
  93. }
  94. #endif
  95. // Test performing a raw db insert to NorthwindIB using the base connection
  96. private int AddComment(string comment, byte seqnum) {
  97. #if ORACLE_EDMX
  98. var time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
  99. var text = String.Format("insert into COMMENT_ (CreatedOn, Comment1, SeqNum) values (TO_DATE('{0}','YYYY-MM-DD HH24:MI:SS'), '{1}', {2})",
  100. time, comment, seqnum);
  101. #else
  102. var time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
  103. var text = String.Format("insert into Comment (CreatedOn, Comment1, SeqNum) values ('{0}', '{1}', {2})",
  104. time, comment, seqnum);
  105. #endif
  106. #if NHIBERNATE
  107. var cmd = Session.CreateSQLQuery(text);
  108. var result = cmd.ExecuteUpdate();
  109. #else
  110. var conn = StoreConnection;
  111. var cmd = conn.CreateCommand();
  112. #if !ORACLE_EDMX
  113. SetCurrentTransaction(cmd);
  114. #endif
  115. cmd.CommandText = text;
  116. var result = cmd.ExecuteNonQuery();
  117. #endif
  118. return result;
  119. }
  120. // Test performing a raw db update to ProduceTPH using the ProduceTPH connection. Requires DTC.
  121. private int UpdateProduceDescription(string comment) {
  122. using (var conn = new SqlConnection("data source=.;initial catalog=ProduceTPH;integrated security=True;multipleactiveresultsets=True;application name=EntityFramework")) {
  123. conn.Open();
  124. var cmd = conn.CreateCommand();
  125. cmd.CommandText = String.Format("update ItemOfProduce set Description='{0}' where id='{1}'",
  126. comment, "13F1C9F5-3189-45FA-BA6E-13314FAFAA92");
  127. var result = cmd.ExecuteNonQuery();
  128. conn.Close();
  129. return result;
  130. }
  131. }
  132. // Use another Context to simulate lookup. Returns Margaret Peacock if employeeId is not specified.
  133. private Employee LookupEmployeeInSeparateContext(bool existingConnection, int employeeId = 4) {
  134. var context2 = existingConnection
  135. #if CODEFIRST_PROVIDER
  136. ? new NorthwindIBContext_CF(EntityConnection)
  137. : new NorthwindIBContext_CF();
  138. #elif DATABASEFIRST_OLD
  139. ? new NorthwindIBContext_EDMX((System.Data.EntityClient.EntityConnection)EntityConnection)
  140. : new NorthwindIBContext_EDMX();
  141. #elif DATABASEFIRST_NEW
  142. ? new NorthwindIBContext_EDMX_2012(EntityConnection)
  143. : new NorthwindIBContext_EDMX_2012();
  144. #elif ORACLE_EDMX
  145. ? new NorthwindIBContext_EDMX_Oracle(EntityConnection)
  146. : new NorthwindIBContext_EDMX_Oracle();
  147. #elif NHIBERNATE
  148. ? new NorthwindNHContext(this)
  149. : new NorthwindNHContext();
  150. #endif
  151. var query = context2.Employees.Where(e => e.EmployeeID == employeeId);
  152. var employee = query.FirstOrDefault();
  153. return employee;
  154. }
  155. protected override bool BeforeSaveEntity(EntityInfo entityInfo) {
  156. if ((string)SaveOptions.Tag == "addProdOnServer") {
  157. Supplier supplier = entityInfo.Entity as Supplier;
  158. Product product = new Product() {
  159. ProductName = "Product added on server"
  160. };
  161. #if CODEFIRST_PROVIDER
  162. if (supplier.Products == null) supplier.Products = new List<Product>();
  163. #endif
  164. supplier.Products.Add(product);
  165. return true;
  166. }
  167. // prohibit any additions of entities of type 'Region'
  168. if (entityInfo.Entity.GetType() == typeof(Region) && entityInfo.EntityState == EntityState.Added) {
  169. var region = entityInfo.Entity as Region;
  170. if (region.RegionDescription.ToLowerInvariant().StartsWith("error")) return false;
  171. }
  172. #if ORACLE_EDMX
  173. // Convert GUIDs in Customer and Order to be compatible with Oracle
  174. if (entityInfo.Entity.GetType() == typeof(Customer)) {
  175. var cust = entityInfo.Entity as Customer;
  176. if (cust.CustomerID != null) {
  177. cust.CustomerID = cust.CustomerID.ToUpperInvariant();
  178. }
  179. } else if (entityInfo.Entity.GetType() == typeof(Order)) {
  180. var order = entityInfo.Entity as Order;
  181. if (order.CustomerID != null) {
  182. order.CustomerID = order.CustomerID.ToUpperInvariant();
  183. }
  184. }
  185. #endif
  186. return base.BeforeSaveEntity(entityInfo);
  187. }
  188. protected override Dictionary<Type, List<EntityInfo>> BeforeSaveEntities(Dictionary<Type, List<EntityInfo>> saveMap) {
  189. var tag = (string)SaveOptions.Tag;
  190. if (tag == "CommentOrderShipAddress.Before") {
  191. var orderInfos = saveMap[typeof(Order)];
  192. byte seq = 1;
  193. foreach (var info in orderInfos) {
  194. var order = (Order)info.Entity;
  195. AddComment(order.ShipAddress, seq++);
  196. }
  197. } else if (tag == "UpdateProduceShipAddress.Before") {
  198. var orderInfos = saveMap[typeof(Order)];
  199. var order = (Order)orderInfos[0].Entity;
  200. UpdateProduceDescription(order.ShipAddress);
  201. } else if (tag == "LookupEmployeeInSeparateContext.Before") {
  202. LookupEmployeeInSeparateContext(false);
  203. } else if (tag == "LookupEmployeeInSeparateContext.SameConnection.Before") {
  204. LookupEmployeeInSeparateContext(true);
  205. } else if (tag == "ValidationError.Before") {
  206. foreach (var type in saveMap.Keys) {
  207. var list = saveMap[type];
  208. foreach (var entityInfo in list) {
  209. var entity = entityInfo.Entity;
  210. var entityError = new EntityError() {
  211. EntityTypeName = type.Name,
  212. ErrorMessage = "Error message for " + type.Name,
  213. ErrorName = "Server-Side Validation",
  214. };
  215. if (entity is Order) {
  216. var order = (Order)entity;
  217. entityError.KeyValues = new object[] { order.OrderID };
  218. entityError.PropertyName = "OrderDate";
  219. }
  220. }
  221. }
  222. } else if (tag == "increaseProductPrice") {
  223. Dictionary<Type, List<EntityInfo>> saveMapAdditions = new Dictionary<Type, List<EntityInfo>>();
  224. foreach (var type in saveMap.Keys) {
  225. if (type == typeof(Category)) {
  226. foreach (var entityInfo in saveMap[type]) {
  227. if (entityInfo.EntityState == EntityState.Modified) {
  228. Category category = (entityInfo.Entity as Category);
  229. var products = this.Context.Products.Where(p => p.CategoryID == category.CategoryID);
  230. foreach (var product in products) {
  231. if (!saveMapAdditions.ContainsKey(typeof(Product)))
  232. saveMapAdditions[typeof(Product)] = new List<EntityInfo>();
  233. var ei = this.CreateEntityInfo(product, EntityState.Modified);
  234. ei.ForceUpdate = true;
  235. var incr = (Convert.ToInt64(product.UnitPrice) % 2) == 0 ? 1 : -1;
  236. product.UnitPrice += incr;
  237. saveMapAdditions[typeof(Product)].Add(ei);
  238. }
  239. }
  240. }
  241. }
  242. }
  243. foreach (var type in saveMapAdditions.Keys) {
  244. if (!saveMap.ContainsKey(type)) {
  245. saveMap[type] = new List<EntityInfo>();
  246. }
  247. foreach (var enInfo in saveMapAdditions[type]) {
  248. saveMap[type].Add(enInfo);
  249. }
  250. }
  251. }
  252. #if DATABASEFIRST_OLD
  253. DataAnnotationsValidator.AddDescriptor(typeof(Customer), typeof(CustomerMetaData));
  254. var validator = new DataAnnotationsValidator(this);
  255. validator.ValidateEntities(saveMap, true);
  256. #endif
  257. return base.BeforeSaveEntities(saveMap);
  258. }
  259. }
  260. #if NHIBERNATE
  261. [BreezeNHController]
  262. #else
  263. [BreezeController]
  264. #endif
  265. public class NorthwindIBModelController : ApiController {
  266. private NorthwindContextProvider ContextProvider;
  267. public NorthwindIBModelController() {
  268. ContextProvider = new NorthwindContextProvider();
  269. }
  270. //[HttpGet]
  271. //public String Metadata() {
  272. // var folder = Path.Combine(HttpRuntime.AppDomainAppPath, "App_Data");
  273. // var fileName = Path.Combine(folder, "metadata.json");
  274. // var jsonMetadata = File.ReadAllText(fileName);
  275. // return jsonMetadata;
  276. //}
  277. //[HttpGet]
  278. //public HttpResponseMessage Metadata() {
  279. // var result = new HttpResponseMessage { Content = new StringContent(ContextProvider.Metadata())};
  280. // result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
  281. // return result;
  282. //}
  283. [HttpGet]
  284. public String Metadata() {
  285. return ContextProvider.Metadata();
  286. }
  287. [HttpPost]
  288. public SaveResult SaveChanges(JObject saveBundle) {
  289. return ContextProvider.SaveChanges(saveBundle);
  290. }
  291. [HttpPost]
  292. public SaveResult SaveWithTransactionScope(JObject saveBundle) {
  293. var txSettings = new TransactionSettings() { TransactionType = TransactionType.TransactionScope };
  294. return ContextProvider.SaveChanges(saveBundle, txSettings);
  295. }
  296. [HttpPost]
  297. public SaveResult SaveWithDbTransaction(JObject saveBundle) {
  298. var txSettings = new TransactionSettings() { TransactionType = TransactionType.DbTransaction };
  299. return ContextProvider.SaveChanges(saveBundle, txSettings);
  300. }
  301. [HttpPost]
  302. public SaveResult SaveWithNoTransaction(JObject saveBundle) {
  303. var txSettings = new TransactionSettings() { TransactionType = TransactionType.None };
  304. return ContextProvider.SaveChanges(saveBundle, txSettings);
  305. }
  306. [HttpPost]
  307. public SaveResult SaveWithComment(JObject saveBundle) {
  308. ContextProvider.BeforeSaveEntitiesDelegate = AddComment;
  309. return ContextProvider.SaveChanges(saveBundle);
  310. }
  311. [HttpPost]
  312. public SaveResult SaveWithExit(JObject saveBundle) {
  313. return new SaveResult() { Entities = new List<Object>(), KeyMappings = new List<KeyMapping>() };
  314. }
  315. [HttpPost]
  316. public SaveResult SaveAndThrow(JObject saveBundle) {
  317. ContextProvider.BeforeSaveEntitiesDelegate = ThrowError;
  318. return ContextProvider.SaveChanges(saveBundle);
  319. }
  320. [HttpPost]
  321. public SaveResult SaveWithEntityErrorsException(JObject saveBundle) {
  322. ContextProvider.BeforeSaveEntitiesDelegate = ThrowEntityErrorsException;
  323. return ContextProvider.SaveChanges(saveBundle);
  324. }
  325. [HttpPost]
  326. public SaveResult SaveWithFreight(JObject saveBundle) {
  327. ContextProvider.BeforeSaveEntityDelegate = CheckFreight;
  328. return ContextProvider.SaveChanges(saveBundle);
  329. }
  330. [HttpPost]
  331. public SaveResult SaveWithFreight2(JObject saveBundle) {
  332. ContextProvider.BeforeSaveEntitiesDelegate = CheckFreightOnOrders;
  333. return ContextProvider.SaveChanges(saveBundle);
  334. }
  335. [HttpPost]
  336. public SaveResult SaveCheckInitializer(JObject saveBundle) {
  337. ContextProvider.BeforeSaveEntitiesDelegate = AddOrder;
  338. return ContextProvider.SaveChanges(saveBundle);
  339. }
  340. [HttpPost]
  341. public SaveResult SaveCheckUnmappedProperty(JObject saveBundle) {
  342. ContextProvider.BeforeSaveEntityDelegate = CheckUnmappedProperty;
  343. return ContextProvider.SaveChanges(saveBundle);
  344. }
  345. [HttpPost]
  346. public SaveResult SaveCheckUnmappedPropertySerialized(JObject saveBundle) {
  347. ContextProvider.BeforeSaveEntityDelegate = CheckUnmappedPropertySerialized;
  348. return ContextProvider.SaveChanges(saveBundle);
  349. }
  350. [HttpPost]
  351. public SaveResult SaveCheckUnmappedPropertySuppressed(JObject saveBundle) {
  352. ContextProvider.BeforeSaveEntityDelegate = CheckUnmappedPropertySuppressed;
  353. return ContextProvider.SaveChanges(saveBundle);
  354. }
  355. private Dictionary<Type, List<EntityInfo>> ThrowError(Dictionary<Type, List<EntityInfo>> saveMap) {
  356. throw new Exception("Deliberately thrown exception");
  357. }
  358. private Dictionary<Type, List<EntityInfo>> ThrowEntityErrorsException(Dictionary<Type, List<EntityInfo>> saveMap) {
  359. List<EntityInfo> orderInfos;
  360. if (saveMap.TryGetValue(typeof(Order), out orderInfos)) {
  361. var errors = orderInfos.Select(oi => {
  362. #if NHIBERNATE
  363. return new EntityError() {
  364. EntityTypeName = typeof(Order).FullName,
  365. ErrorMessage = "Cannot save orders with this save method",
  366. ErrorName = "WrongMethod",
  367. KeyValues = new object[] { ((Order) oi.Entity).OrderID },
  368. PropertyName = "OrderID"
  369. };
  370. #else
  371. return new EFEntityError(oi, "WrongMethod", "Cannot save orders with this save method", "OrderID");
  372. #endif
  373. });
  374. var ex = new EntityErrorsException("test of custom exception message", errors);
  375. // if you want to see a different error status code use this.
  376. // ex.StatusCode = HttpStatusCode.Conflict; // Conflict = 409 ; default is Forbidden (403).
  377. throw ex;
  378. }
  379. return saveMap;
  380. }
  381. private Dictionary<Type, List<EntityInfo>> AddOrder(Dictionary<Type, List<EntityInfo>> saveMap) {
  382. var order = new Order();
  383. order.OrderDate = DateTime.Today;
  384. var ei = ContextProvider.CreateEntityInfo(order);
  385. List<EntityInfo> orderInfos;
  386. if (!saveMap.TryGetValue(typeof(Order), out orderInfos)) {
  387. orderInfos = new List<EntityInfo>();
  388. saveMap.Add(typeof(Order), orderInfos);
  389. }
  390. orderInfos.Add(ei);
  391. return saveMap;
  392. }
  393. private Dictionary<Type, List<EntityInfo>> CheckFreightOnOrders(Dictionary<Type, List<EntityInfo>> saveMap) {
  394. List<EntityInfo> entityInfos;
  395. if (saveMap.TryGetValue(typeof(Order), out entityInfos)) {
  396. foreach (var entityInfo in entityInfos) {
  397. CheckFreight(entityInfo);
  398. }
  399. }
  400. return saveMap;
  401. }
  402. private bool CheckFreight(EntityInfo entityInfo) {
  403. if ((ContextProvider.SaveOptions.Tag as String) == "freight update") {
  404. var order = entityInfo.Entity as Order;
  405. order.Freight = order.Freight + 1;
  406. } else if ((ContextProvider.SaveOptions.Tag as String) == "freight update-ov") {
  407. var order = entityInfo.Entity as Order;
  408. order.Freight = order.Freight + 1;
  409. entityInfo.OriginalValuesMap["Freight"] = null;
  410. } else if ((ContextProvider.SaveOptions.Tag as String) == "freight update-force") {
  411. var order = entityInfo.Entity as Order;
  412. order.Freight = order.Freight + 1;
  413. entityInfo.ForceUpdate = true;
  414. }
  415. return true;
  416. }
  417. private Dictionary<Type, List<EntityInfo>> AddComment(Dictionary<Type, List<EntityInfo>> saveMap) {
  418. var comment = new Comment();
  419. var tag = ContextProvider.SaveOptions.Tag;
  420. comment.Comment1 = (tag == null) ? "Generic comment" : tag.ToString();
  421. comment.CreatedOn = DateTime.Now;
  422. comment.SeqNum = 1;
  423. var ei = ContextProvider.CreateEntityInfo(comment);
  424. List<EntityInfo> commentInfos;
  425. if (!saveMap.TryGetValue(typeof(Comment), out commentInfos)) {
  426. commentInfos = new List<EntityInfo>();
  427. saveMap.Add(typeof(Comment), commentInfos);
  428. }
  429. commentInfos.Add(ei);
  430. return saveMap;
  431. }
  432. private bool CheckUnmappedProperty(EntityInfo entityInfo) {
  433. var unmappedValue = entityInfo.UnmappedValuesMap["myUnmappedProperty"];
  434. if ((String)unmappedValue != "anything22") {
  435. throw new Exception("wrong value for unmapped property: " + unmappedValue);
  436. }
  437. Customer cust = entityInfo.Entity as Customer;
  438. return false;
  439. }
  440. private bool CheckUnmappedPropertySuppressed(EntityInfo entityInfo) {
  441. if (entityInfo.UnmappedValuesMap != null) {
  442. throw new Exception("unmapped properties should have been suppressed");
  443. }
  444. return false;
  445. }
  446. private bool CheckUnmappedPropertySerialized(EntityInfo entityInfo) {
  447. var unmappedValue = entityInfo.UnmappedValuesMap["myUnmappedProperty"];
  448. if ((String)unmappedValue != "ANYTHING22") {
  449. throw new Exception("wrong value for unmapped property: " + unmappedValue);
  450. }
  451. var anotherOne = entityInfo.UnmappedValuesMap["anotherOne"];
  452. if (((dynamic) anotherOne).z[5].foo.Value != 4) {
  453. throw new Exception("wrong value for 'anotherOne.z[5].foo'");
  454. }
  455. if (((dynamic)anotherOne).extra.Value != 666) {
  456. throw new Exception("wrong value for 'anotherOne.extra'");
  457. }
  458. Customer cust = entityInfo.Entity as Customer;
  459. if (cust.CompanyName.ToUpper() != cust.CompanyName) {
  460. throw new Exception("Uppercasing of company name did not occur");
  461. }
  462. return false;
  463. }
  464. #region standard queries
  465. [HttpGet]
  466. public List<Employee> QueryInvolvingMultipleEntities() {
  467. #if NHIBERNATE
  468. // need to figure out what to do here
  469. //return new List<Employee>();
  470. var dc0 = new NorthwindNHContext();
  471. var dc = new NorthwindNHContext();
  472. #elif CODEFIRST_PROVIDER
  473. var dc0 = new NorthwindIBContext_CF();
  474. var dc = new EFContextProvider<NorthwindIBContext_CF>();
  475. #elif DATABASEFIRST_OLD
  476. var dc0 = new NorthwindIBContext_EDMX();
  477. var dc = new EFContextProvider<NorthwindIBContext_EDMX>();
  478. #elif DATABASEFIRST_NEW
  479. var dc0 = new NorthwindIBContext_EDMX_2012();
  480. var dc = new EFContextProvider<NorthwindIBContext_EDMX_2012>();
  481. #elif ORACLE_EDMX
  482. var dc0 = new NorthwindIBContext_EDMX_Oracle();
  483. var dc = new EFContextProvider<NorthwindIBContext_EDMX_Oracle>();
  484. #endif
  485. //the query executes using pure EF
  486. var query0 = (from t1 in dc0.Employees
  487. where (from t2 in dc0.Orders select t2.EmployeeID).Distinct().Contains(t1.EmployeeID)
  488. select t1);
  489. var result0 = query0.ToList();
  490. //the same query fails if using EFContextProvider
  491. dc0 = dc.Context;
  492. var query = (from t1 in dc0.Employees
  493. where (from t2 in dc0.Orders select t2.EmployeeID).Distinct().Contains(t1.EmployeeID)
  494. select t1);
  495. var result = query.ToList();
  496. return result;
  497. }
  498. [HttpGet]
  499. #if NHIBERNATE
  500. [BreezeNHQueryable(MaxAnyAllExpressionDepth = 3)]
  501. #else
  502. [BreezeQueryable(MaxAnyAllExpressionDepth = 3)]
  503. #endif
  504. public IQueryable<Customer> Customers() {
  505. var custs = ContextProvider.Context.Customers;
  506. return custs;
  507. }
  508. [HttpGet]
  509. public IQueryable<Customer> CustomersStartingWith(string companyName) {
  510. if (companyName == "null") {
  511. throw new Exception("nulls should not be passed as 'null'");
  512. }
  513. if (String.IsNullOrEmpty(companyName)) {
  514. companyName = "";
  515. }
  516. var custs = ContextProvider.Context.Customers.Where(c => c.CompanyName.StartsWith(companyName));
  517. return custs;
  518. }
  519. [HttpGet]
  520. public Object CustomerCountsByCountry() {
  521. return ContextProvider.Context.Customers.GroupBy(c => c.Country).Select(g => new { g.Key, Count = g.Count() });
  522. }
  523. [HttpGet]
  524. public Customer CustomerWithScalarResult() {
  525. return ContextProvider.Context.Customers.First();
  526. }
  527. [HttpGet]
  528. public IQueryable<Customer> CustomersWithHttpError() {
  529. var responseMsg = new HttpResponseMessage(HttpStatusCode.NotFound);
  530. responseMsg.Content = new StringContent("Custom error message");
  531. responseMsg.ReasonPhrase = "Custom Reason";
  532. throw new HttpResponseException(responseMsg);
  533. }
  534. [HttpGet]
  535. #if NHIBERNATE
  536. [BreezeNHQueryable(MaxExpansionDepth = 3)]
  537. #else
  538. [BreezeQueryable(MaxExpansionDepth = 3)]
  539. #endif
  540. public IQueryable<Order> Orders() {
  541. var orders = ContextProvider.Context.Orders;
  542. return orders;
  543. }
  544. [HttpGet]
  545. public IQueryable<Employee> Employees() {
  546. return ContextProvider.Context.Employees;
  547. }
  548. [HttpGet]
  549. [BreezeQueryable]
  550. public IEnumerable<Employee> EnumerableEmployees() {
  551. return ContextProvider.Context.Employees.ToList();
  552. }
  553. [HttpGet]
  554. public IQueryable<Employee> EmployeesFilteredByCountryAndBirthdate(DateTime birthDate, string country) {
  555. return ContextProvider.Context.Employees.Where(emp => emp.BirthDate >= birthDate && emp.Country == country);
  556. }
  557. [HttpGet]
  558. public IQueryable<OrderDetail> OrderDetails() {
  559. return ContextProvider.Context.OrderDetails;
  560. }
  561. [HttpGet]
  562. public IQueryable<Product> Products() {
  563. return ContextProvider.Context.Products;
  564. }
  565. [HttpGet]
  566. public IQueryable<Supplier> Suppliers() {
  567. return ContextProvider.Context.Suppliers;
  568. }
  569. [HttpGet]
  570. public IQueryable<Region> Regions() {
  571. return ContextProvider.Context.Regions;
  572. }
  573. [HttpGet]
  574. public IQueryable<Territory> Territories() {
  575. return ContextProvider.Context.Territories;
  576. }
  577. [HttpGet]
  578. public IQueryable<Category> Categories() {
  579. return ContextProvider.Context.Categories;
  580. }
  581. [HttpGet]
  582. public IQueryable<Role> Roles() {
  583. return ContextProvider.Context.Roles;
  584. }
  585. [HttpGet]
  586. public IQueryable<User> Users() {
  587. return ContextProvider.Context.Users;
  588. }
  589. [HttpGet]
  590. public IQueryable<TimeLimit> TimeLimits() {
  591. return ContextProvider.Context.TimeLimits;
  592. }
  593. [HttpGet]
  594. public IQueryable<TimeGroup> TimeGroups() {
  595. return ContextProvider.Context.TimeGroups;
  596. }
  597. [HttpGet]
  598. public IQueryable<Comment> Comments() {
  599. return ContextProvider.Context.Comments;
  600. }
  601. [HttpGet]
  602. public IQueryable<UnusualDate> UnusualDates() {
  603. return ContextProvider.Context.UnusualDates;
  604. }
  605. #if ! DATABASEFIRST_OLD
  606. [HttpGet]
  607. public IQueryable<Geospatial> Geospatials() {
  608. return ContextProvider.Context.Geospatials;
  609. }
  610. #endif
  611. #endregion
  612. #region named queries
  613. [HttpGet]
  614. public Customer CustomerFirstOrDefault() {
  615. var customer = ContextProvider.Context.Customers.Where(c => c.CompanyName.StartsWith("blah")).FirstOrDefault();
  616. return customer;
  617. }
  618. [HttpGet]
  619. // AltCustomers will not be in the resourceName/entityType map;
  620. public IQueryable<Customer> AltCustomers() {
  621. return ContextProvider.Context.Customers;
  622. }
  623. [HttpGet]
  624. public IQueryable<Employee> SearchEmployees([FromUri] int[] employeeIds) {
  625. var query = ContextProvider.Context.Employees.AsQueryable();
  626. if (employeeIds.Length > 0) {
  627. query = query.Where(emp => employeeIds.Contains(emp.EmployeeID));
  628. var result = query.ToList();
  629. }
  630. return query;
  631. }
  632. [HttpGet]
  633. public IQueryable<Customer> SearchCustomers([FromUri] CustomerQBE qbe) {
  634. // var query = ContextProvider.Context.Customers.Where(c =>
  635. // c.CompanyName.StartsWith(qbe.CompanyName));
  636. var ok = qbe != null && qbe.CompanyName != null & qbe.ContactNames.Length > 0 && qbe.City.Length > 1;
  637. if (!ok) {
  638. throw new Exception("qbe error");
  639. }
  640. // just testing that qbe actually made it in not attempted to write qbe logic here
  641. // so just return first 3 customers.
  642. return ContextProvider.Context.Customers.Take(3);
  643. }
  644. [HttpGet]
  645. public IQueryable<Customer> SearchCustomers2([FromUri] CustomerQBE[] qbeList) {
  646. if (qbeList.Length < 2) {
  647. throw new Exception("all least two items must be passed in");
  648. }
  649. var ok = qbeList.All(qbe => {
  650. return qbe.CompanyName != null & qbe.ContactNames.Length > 0 && qbe.City.Length > 1;
  651. });
  652. if (!ok) {
  653. throw new Exception("qbeList error");
  654. }
  655. // just testing that qbe actually made it in not attempted to write qbe logic here
  656. // so just return first 3 customers.
  657. return ContextProvider.Context.Customers.Take(3);
  658. }
  659. public class CustomerQBE {
  660. public String CompanyName { get; set; }
  661. public String[] ContactNames { get; set; }
  662. public String City { get; set; }
  663. }
  664. [HttpGet]
  665. public IQueryable<Customer> CustomersOrderedStartingWith(string companyName) {
  666. var customers = ContextProvider.Context.Customers.Where(c => c.CompanyName.StartsWith(companyName)).OrderBy(cust => cust.CompanyName);
  667. var list = customers.ToList();
  668. return customers;
  669. }
  670. [HttpGet]
  671. public IQueryable<Employee> EmployeesMultipleParams(int employeeID, string city) {
  672. // HACK:
  673. if (city == "null") {
  674. city = null;
  675. }
  676. var emps = ContextProvider.Context.Employees.Where(emp => emp.EmployeeID == employeeID || emp.City.Equals(city));
  677. return emps;
  678. }
  679. [HttpGet]
  680. public IEnumerable<Object> Lookup1Array() {
  681. var regions = ContextProvider.Context.Regions;
  682. var lookups = new List<Object>();
  683. lookups.Add(new {regions = regions});
  684. return lookups;
  685. }
  686. [HttpGet]
  687. public object Lookups() {
  688. var regions = ContextProvider.Context.Regions;
  689. var territories = ContextProvider.Context.Territories;
  690. var categories = ContextProvider.Context.Categories;
  691. var lookups = new { regions, territories, categories };
  692. return lookups;
  693. }
  694. [HttpGet]
  695. public IEnumerable<Object> LookupsEnumerableAnon() {
  696. var regions = ContextProvider.Context.Regions;
  697. var territories = ContextProvider.Context.Territories;
  698. var categories = ContextProvider.Context.Categories;
  699. var lookups = new List<Object>();
  700. lookups.Add(new {regions = regions, territories = territories, categories = categories});
  701. return lookups;
  702. }
  703. [HttpGet]
  704. public IQueryable<Object> CompanyNames() {
  705. var stuff = ContextProvider.Context.Customers.Select(c => c.CompanyName);
  706. return stuff;
  707. }
  708. [HttpGet]
  709. public IQueryable<Object> CompanyNamesAndIds() {
  710. var stuff = ContextProvider.Context.Customers.Select(c => new { c.CompanyName, c.CustomerID });
  711. return stuff;
  712. }
  713. [HttpGet]
  714. public IQueryable<CustomerDTO> CompanyNamesAndIdsAsDTO() {
  715. var stuff = ContextProvider.Context.Customers.Select(c => new CustomerDTO() { CompanyName = c.CompanyName, CustomerID = c.CustomerID });
  716. return stuff;
  717. }
  718. public class CustomerDTO {
  719. public CustomerDTO() {
  720. }
  721. public CustomerDTO(String companyName, Guid customerID) {
  722. CompanyName = companyName;
  723. CustomerID = customerID;
  724. }
  725. public Guid CustomerID { get; set; }
  726. public String CompanyName { get; set; }
  727. public AnotherType AnotherItem { get; set; }
  728. }
  729. public class AnotherType {
  730. }
  731. [HttpGet]
  732. public IQueryable<Object> CustomersWithBigOrders() {
  733. var stuff = ContextProvider.Context.Customers.Where(c => c.Orders.Any(o => o.Freight > 100)).Select(c => new { Customer = c, BigOrders = c.Orders.Where(o => o.Freight > 100) });
  734. return stuff;
  735. }
  736. [HttpGet]
  737. #if NHIBERNATE
  738. public IQueryable<Object> CompanyInfoAndOrders(System.Web.Http.OData.Query.ODataQueryOptions options) {
  739. // Need to handle this specially for NH, to prevent $top being applied to Orders
  740. var query = ContextProvider.Context.Customers;
  741. var queryHelper = new NHQueryHelper();
  742. // apply the $filter, $skip, $top to the query
  743. var query2 = queryHelper.ApplyQuery(query, options);
  744. // execute query, then expand the Orders
  745. var r = query2.Cast<Customer>().ToList();
  746. NHInitializer.InitializeList(r, "Orders");
  747. // after all is loaded, create the projection
  748. var stuff = r.AsQueryable().Select(c => new { c.CompanyName, c.CustomerID, c.Orders });
  749. queryHelper.ConfigureFormatter(Request, query);
  750. #else
  751. public IQueryable<Object> CompanyInfoAndOrders() {
  752. var stuff = ContextProvider.Context.Customers.Select(c => new { c.CompanyName, c.CustomerID, c.Orders });
  753. #endif
  754. return stuff;
  755. }
  756. [HttpGet]
  757. public Object CustomersAndProducts() {
  758. var stuff = new { Customers = ContextProvider.Context.Customers.ToList(), Products = ContextProvider.Context.Products.ToList() };
  759. return stuff;
  760. }
  761. [HttpGet]
  762. public IQueryable<Object> TypeEnvelopes() {
  763. var stuff = this.GetType().Assembly.GetTypes()
  764. .Select(t => new { t.Assembly.FullName, t.Name, t.Namespace })
  765. .AsQueryable();
  766. return stuff;
  767. }
  768. [HttpGet]
  769. public IQueryable<Customer> CustomersAndOrders() {
  770. var custs = ContextProvider.Context.Customers.Include("Orders");
  771. return custs;
  772. }
  773. [HttpGet]
  774. public IQueryable<Order> OrdersAndCustomers() {
  775. var orders = ContextProvider.Context.Orders.Include("Customer");
  776. return orders;
  777. }
  778. [HttpGet]
  779. public IQueryable<Customer> CustomersStartingWithA() {
  780. var custs = ContextProvider.Context.Customers.Where(c => c.CompanyName.StartsWith("A"));
  781. return custs;
  782. }
  783. [HttpGet]
  784. #if NHIBERNATE
  785. [BreezeNHQueryable]
  786. #else
  787. [BreezeQueryable]
  788. #endif
  789. public HttpResponseMessage CustomersAsHRM() {
  790. var customers = ContextProvider.Context.Customers.Cast<Customer>();
  791. var response = Request.CreateResponse(HttpStatusCode.OK, customers);
  792. return response;
  793. }
  794. #endregion
  795. }
  796. }