PageRenderTime 52ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/WriteTest.cs

https://bitbucket.org/foobar22/mono
C# | 859 lines | 667 code | 124 blank | 68 comment | 67 complexity | 9e1a88a09dedbaf58084332cd3869f3a MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0, Unlicense, Apache-2.0, LGPL-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.Collections.Generic;
  28. using System.Text;
  29. using System.Linq;
  30. using System.Linq.Expressions;
  31. using NUnit.Framework;
  32. using Test_NUnit;
  33. using System.ComponentModel;
  34. using System.Data.Linq.Mapping;
  35. using nwind;
  36. #if MONO_STRICT
  37. using System.Data.Linq;
  38. #if MONO
  39. using DbLinq.Util;
  40. #endif
  41. #else
  42. using DbLinq.Data.Linq;
  43. using DbLinq.Util;
  44. #endif
  45. #if ORACLE
  46. using Id = System.Decimal;
  47. #else
  48. using Id = System.Int32;
  49. #endif
  50. // test ns
  51. #if MYSQL
  52. namespace Test_NUnit_MySql
  53. #elif ORACLE && ODP
  54. namespace Test_NUnit_OracleODP
  55. #elif ORACLE
  56. namespace Test_NUnit_Oracle
  57. #elif POSTGRES
  58. namespace Test_NUnit_PostgreSql
  59. #elif SQLITE
  60. namespace Test_NUnit_Sqlite
  61. #elif INGRES
  62. namespace Test_NUnit_Ingres
  63. #elif MSSQL && L2SQL
  64. namespace Test_NUnit_MsSql_Strict
  65. #elif MSSQL
  66. namespace Test_NUnit_MsSql
  67. #elif FIREBIRD
  68. namespace Test_NUnit_Firebird
  69. #endif
  70. {
  71. [TestFixture]
  72. public class WriteTest : TestBase
  73. {
  74. [SetUp]
  75. public void TestSetup()
  76. {
  77. base.BaseSetUp();
  78. Profiler.At("START: WriteTest.TestSetup()");
  79. Northwind db = CreateDB();
  80. // "[Products]" gets converted to "Products".
  81. //This is a DbLinq-defined escape sequence, by Pascal.
  82. //db.ExecuteCommand("DELETE FROM [Products] WHERE [ProductName] like 'temp%'");
  83. var deleteProducts = db.Products.Where(p => p.ProductName.StartsWith("temp")).ToList();
  84. db.Products.DeleteAllOnSubmit(deleteProducts);
  85. var deleteCategories = db.Categories.Where(c => c.CategoryName.StartsWith("temp")).ToList();
  86. db.Categories.DeleteAllOnSubmit(deleteCategories);
  87. db.SubmitChanges();
  88. Profiler.At("END: WriteTest.TestSetup()");
  89. }
  90. #region Tests 'E' test live object cache
  91. [Test]
  92. public void E1_LiveObjectsAreUnique()
  93. {
  94. //grab an object twice, make sure we get the same object each time
  95. Northwind db = CreateDB();
  96. var q = from p in db.Products select p;
  97. Product product1 = q.First();
  98. Product product2 = q.First();
  99. Assert.AreSame(product1, product2);
  100. string uniqueStr = "Unique" + Environment.TickCount;
  101. product1.QuantityPerUnit = uniqueStr;
  102. bool isSameObject1 = product2.QuantityPerUnit == uniqueStr;
  103. Assert.IsTrue(isSameObject1, "Expected product1 and product2 to be the same live object, but their fields are different");
  104. object oProduct1 = product1;
  105. object oProduct2 = product2;
  106. bool isSameObject2 = oProduct1 == oProduct2;
  107. Assert.IsTrue(isSameObject2, "Expected product1 and product2 to be the same live object, but their fields are different");
  108. }
  109. [Test]
  110. public void E2_LiveObjectsAreUnique_Scalar()
  111. {
  112. //grab an object twice, make sure we get the same object each time
  113. Northwind db = CreateDB();
  114. var q = from p in db.Products select p;
  115. Product product1 = q.First(p => p.ProductName == "Chai");
  116. Product product2 = q.Single(p => p.ProductName == "Chai");
  117. bool isSame = object.ReferenceEquals(product1, product2);
  118. Assert.IsTrue(isSame, "Expected product2 and product2 to be the same live object");
  119. }
  120. #if MYSQL && USE_ALLTYPES
  121. [Test]
  122. public void E3_UpdateEnum()
  123. {
  124. Northwind db = CreateDB();
  125. var q = from at in db.Alltypes where at.int_ == 1 select at;
  126. Alltype row = q.First();
  127. DbLinq_EnumTest newValue = row.DbLinq_EnumTest == DbLinq_EnumTest.BB
  128. ? DbLinq_EnumTest.CC
  129. : DbLinq_EnumTest.BB;
  130. row.DbLinq_EnumTest = newValue;
  131. db.SubmitChanges();
  132. }
  133. #endif
  134. #endregion
  135. #region Tests 'G' do insertion
  136. private int insertProduct_priv()
  137. {
  138. Northwind db = CreateDB();
  139. Product newProd = new Product();
  140. newProd.CategoryID = db.Categories.First().CategoryID;
  141. newProd.ProductName = "Temp." + Environment.TickCount;
  142. newProd.QuantityPerUnit = "33 1/2";
  143. db.Products.InsertOnSubmit(newProd);
  144. db.SubmitChanges();
  145. Assert.Greater(newProd.ProductID, 0, "After insertion, ProductID should be non-zero");
  146. //Assert.IsFalse(newProd.IsModified, "After insertion, Product.IsModified should be false");
  147. return (int)newProd.ProductID; //this test cab be used from delete tests
  148. }
  149. [Test]
  150. public void G1_InsertProduct()
  151. {
  152. insertProduct_priv();
  153. }
  154. [Test]
  155. public void G2_DeleteTest()
  156. {
  157. int insertedID = insertProduct_priv();
  158. Assert.Greater(insertedID, 0, "DeleteTest cannot operate if row was not inserted");
  159. Northwind db = CreateDB();
  160. var q = from p in db.Products where p.ProductID == insertedID select p;
  161. List<Product> insertedProducts = q.ToList();
  162. foreach (Product insertedProd in insertedProducts)
  163. {
  164. db.Products.DeleteOnSubmit(insertedProd);
  165. }
  166. db.SubmitChanges();
  167. int numLeft = (from p in db.Products where p.ProductID == insertedID select p).Count();
  168. Assert.AreEqual(numLeft, 0, "After deletion, expected count of Products with ID=" + insertedID + " to be zero, instead got " + numLeft);
  169. }
  170. [Test]
  171. public void G3_DeleteTest()
  172. {
  173. int insertedID = insertProduct_priv();
  174. Assert.Greater(insertedID, 0, "DeleteTest cannot operate if row was not inserted");
  175. Northwind db = CreateDB();
  176. var q = from p in db.Products where p.ProductID == insertedID select p;
  177. List<Product> insertedProducts = q.ToList();
  178. foreach (Product insertedProd in insertedProducts)
  179. {
  180. db.Products.DeleteOnSubmit(insertedProd);
  181. }
  182. db.SubmitChanges();
  183. int numLeft = (from p in db.Products where p.ProductID == insertedID select p).Count();
  184. Assert.AreEqual(numLeft, 0, "After deletion, expected count of Products with ID=" + insertedID + " to be zero, instead got " + numLeft);
  185. }
  186. [Test]
  187. public void G4_DuplicateSubmitTest()
  188. {
  189. Northwind db = CreateDB();
  190. int productCount1 = db.Products.Count();
  191. #if INGRES && !MONO_STRICT
  192. Product p_temp = new Product { ProductName = "temp_g4", Discontinued = "N" };
  193. #else
  194. Product p_temp = new Product { ProductName = "temp_g4", Discontinued = false };
  195. #endif
  196. db.Products.InsertOnSubmit(p_temp);
  197. db.SubmitChanges();
  198. db.SubmitChanges();
  199. int productCount2 = db.Products.Count();
  200. Assert.IsTrue(productCount2 == productCount1 + 1, "Expected product count to grow by one");
  201. }
  202. /// <summary>
  203. /// there is a bug in v0.14 where fields cannot be updated to be null.
  204. /// </summary>
  205. [Test]
  206. public void G5_SetFieldToNull()
  207. {
  208. string productName = "temp_G5_" + Environment.TickCount;
  209. Northwind db = CreateDB();
  210. #if ORACLE
  211. //todo fix Oracle
  212. Product p1 = new Product { ProductName = productName, Discontinued = false, UnitPrice = 11 };
  213. #elif INGRES && !MONO_STRICT
  214. Product p1 = new Product { ProductName = productName, Discontinued = "N", UnitPrice = 11m };
  215. #else
  216. Product p1 = new Product { ProductName = productName, Discontinued = false, UnitPrice = 11m };
  217. #endif
  218. db.Products.InsertOnSubmit(p1);
  219. db.SubmitChanges();
  220. p1.UnitPrice = null;
  221. db.SubmitChanges();
  222. Northwind db3 = CreateDB();
  223. Product p3 = db3.Products.Single(p => p.ProductName == productName);
  224. Assert.IsNull(p3.UnitPrice);
  225. }
  226. /// <summary>
  227. /// there is a bug in v0.14 where table Customers cannot be updated,
  228. /// because quotes where missing around the primaryKey in the UPDATE statement.
  229. /// </summary>
  230. [Test]
  231. public void G6_UpdateTableWithStringPK()
  232. {
  233. Northwind db = CreateDB();
  234. var customer = new Customer
  235. {
  236. CompanyName = "Test Company",
  237. ContactName = "Test Customer",
  238. CustomerID = "BT___",
  239. };
  240. db.Customers.InsertOnSubmit(customer);
  241. db.SubmitChanges();
  242. Customer BT = db.Customers.Single(c => c.CustomerID == "BT___");
  243. BT.Country = "U.K.";
  244. db.SubmitChanges();
  245. db.Customers.DeleteOnSubmit(customer);
  246. db.SubmitChanges();
  247. }
  248. [Test]
  249. public void G7_InsertTableWithStringPK()
  250. {
  251. Northwind db = CreateDB();
  252. db.ExecuteCommand("DELETE FROM [Customers] WHERE [CustomerID]='TEMP_'");
  253. Customer custTemp = new Customer
  254. {
  255. CustomerID = "TEMP_",
  256. CompanyName = "Magellan",
  257. ContactName = "Antonio Pigafetta",
  258. City = "Lisboa",
  259. };
  260. db.Customers.InsertOnSubmit(custTemp);
  261. db.SubmitChanges();
  262. }
  263. [Test]
  264. public void G8_DeleteTableWithStringPK()
  265. {
  266. Northwind db = CreateDB();
  267. Customer cust = (from c in db.Customers
  268. where c.CustomerID == "TEMP_"
  269. select c).Single();
  270. db.Customers.DeleteOnSubmit(cust);
  271. db.SubmitChanges();
  272. }
  273. [Test]
  274. public void G9_UpdateOnlyChangedProperty()
  275. {
  276. Northwind db = CreateDB();
  277. var cust = (from c in db.Customers
  278. select c).First();
  279. var old = cust.City;
  280. cust.City = "Tallinn";
  281. db.SubmitChanges();
  282. db.SubmitChanges(); // A second call does not update anything
  283. //exposes bug:
  284. //Npgsql.NpgsqlException was unhandled
  285. //Message="ERROR: 23502: null value in column \"companyname\" violates not-null constraint"
  286. cust.City = old;
  287. db.SubmitChanges();
  288. }
  289. #if POSTGRES
  290. public class Northwind1 : Northwind
  291. {
  292. public Northwind1(System.Data.IDbConnection connection)
  293. : base(connection) { }
  294. [System.Data.Linq.Mapping.Table(Name = "cust1")]
  295. public class Cust1
  296. {
  297. string _customerid;
  298. [System.Data.Linq.Mapping.Column(Storage = "_customerid",
  299. Name = "customerid", IsPrimaryKey = true,
  300. DbType = "char(10)",
  301. IsDbGenerated = true,
  302. Expression = "nextval('seq8')")]
  303. public string CustomerId
  304. {
  305. get { return _customerid; }
  306. set { _customerid = value; }
  307. }
  308. // Dummy property is required only as workaround over empty insert list bug
  309. // If this bug is fixed this may be removed
  310. string _dummy;
  311. [System.Data.Linq.Mapping.Column(Storage = "_dummy",
  312. DbType = "text", Name = "dummy")]
  313. public string Dummy
  314. {
  315. get;
  316. set;
  317. }
  318. }
  319. public Table<Cust1> Cust1s
  320. {
  321. get
  322. {
  323. return base.GetTable<Cust1>();
  324. }
  325. }
  326. }
  327. [Test]
  328. public void G10_InsertCharSerialPrimaryKey()
  329. {
  330. Northwind dbo = CreateDB();
  331. Northwind1 db = new Northwind1(dbo.Connection);
  332. try
  333. {
  334. db.ExecuteCommand(
  335. @"create sequence seq8;
  336. create temp table cust1 ( CustomerID char(10) DEFAULT nextval('seq8'),
  337. dummy text
  338. );
  339. ");
  340. Table<Northwind1.Cust1> cust1s =
  341. db.GetTable<Northwind1.Cust1>();
  342. var cust1 = new Northwind1.Cust1();
  343. cust1.Dummy = "";
  344. db.Cust1s.InsertOnSubmit(cust1);
  345. db.SubmitChanges();
  346. Assert.IsNotNull(cust1.CustomerId);
  347. }
  348. finally
  349. {
  350. try { db.ExecuteCommand("drop table cust1;"); }
  351. catch { }
  352. try { db.ExecuteCommand("drop sequence seq8;"); }
  353. catch { }
  354. }
  355. }
  356. #endif
  357. public class NorthwindG11 : Northwind
  358. {
  359. public NorthwindG11(System.Data.IDbConnection connection)
  360. : base(connection) { }
  361. [Table(Name = "rid")]
  362. public class Rid : INotifyPropertyChanged
  363. {
  364. protected int _id;
  365. protected int _reanr;
  366. #if INGRES
  367. [System.Data.Linq.Mapping.Column(Storage = "_id", Name = "id", DbType = "integer", IsPrimaryKey = true, IsDbGenerated = true, Expression = "next value for rid_id1_seq")]
  368. #else
  369. [System.Data.Linq.Mapping.Column(Storage = "_id", Name = "id", DbType = "integer", IsPrimaryKey = true, IsDbGenerated = true, Expression = "nextval('rid_id1_seq')")]
  370. #endif
  371. public int Id
  372. {
  373. get { return _id; }
  374. set
  375. {
  376. _id = value;
  377. OnPropertyChanged("Id");
  378. }
  379. }
  380. #if INGRES
  381. [System.Data.Linq.Mapping.Column(Storage = "_reanr", Name = "reanr", DbType = "integer", IsDbGenerated = true, CanBeNull = false, Expression = "next value for rid_reanr_seq")]
  382. #else
  383. [System.Data.Linq.Mapping.Column(Storage = "_reanr", Name = "reanr", DbType = "integer", IsDbGenerated = true, CanBeNull = false, Expression = "nextval('rid_reanr_seq')")]
  384. #endif
  385. public int Reanr
  386. {
  387. get { return _reanr; }
  388. set
  389. {
  390. _reanr = value;
  391. OnPropertyChanged("Reanr");
  392. }
  393. }
  394. #region INotifyPropertyChanged handling
  395. public event PropertyChangedEventHandler PropertyChanged;
  396. protected virtual void OnPropertyChanged(string propertyName)
  397. {
  398. if (PropertyChanged != null)
  399. {
  400. PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  401. }
  402. }
  403. #endregion
  404. }
  405. public Table<Rid> Rids
  406. {
  407. get
  408. {
  409. return base.GetTable<Rid>();
  410. }
  411. }
  412. }
  413. #if (POSTGRES || INGRES) && !MONO_STRICT
  414. #if !DEBUG && POSTGRES
  415. [Explicit]
  416. #endif
  417. [Test]
  418. public void G11_TwoSequencesInTable()
  419. {
  420. Northwind dbo = CreateDB();
  421. NorthwindG11 db = new NorthwindG11(dbo.Connection);
  422. db.ExecuteCommand(@"create sequence rid_id1_seq");
  423. db.ExecuteCommand(@"create sequence rid_reanr_seq");
  424. #if INGRES
  425. db.ExecuteCommand(@"create table Rid ( id int primary key DEFAULT rid_id1_seq.nextval, reanr int DEFAULT rid_reanr_seq.nextval)");
  426. #else
  427. db.ExecuteCommand(@"create temp table Rid ( id int primary key DEFAULT nextval('rid_id1_seq'), reanr int DEFAULT nextval('rid_reanr_seq'))");
  428. #endif
  429. DbLinq.Data.Linq.Table<NorthwindG11.Rid> Rids = db.GetTable<NorthwindG11.Rid>();
  430. var Rid = new NorthwindG11.Rid();
  431. Rid.Reanr = 22;
  432. Exception e = null;
  433. db.Rids.InsertOnSubmit(Rid);
  434. Rid = new NorthwindG11.Rid();
  435. Rid.Reanr = 23;
  436. db.Rids.InsertOnSubmit(Rid);
  437. try
  438. {
  439. db.SubmitChanges();
  440. }
  441. catch (Exception ex)
  442. {
  443. e = ex;
  444. }
  445. db.ExecuteCommand("drop table rid");
  446. db.ExecuteCommand("drop sequence rid_reanr_seq");
  447. db.ExecuteCommand("drop sequence rid_id1_seq");
  448. if (e != null)
  449. {
  450. throw e;
  451. }
  452. Assert.AreEqual(2, Rid.Id);
  453. Assert.AreEqual(23, Rid.Reanr);
  454. }
  455. #endif
  456. #if !DEBUG && (SQLITE || (MSSQL && !L2SQL))
  457. [Explicit]
  458. #endif
  459. [Test]
  460. public void G12_EmptyInsertList()
  461. {
  462. Northwind db = CreateDB();
  463. Region newRegion = new Region() { RegionDescription = "" }; // RegionDescription must be non-null
  464. db.Regions.InsertOnSubmit(newRegion);
  465. db.SubmitChanges();
  466. Assert.IsNotNull(newRegion.RegionID);
  467. db.Regions.DeleteOnSubmit(newRegion);
  468. db.SubmitChanges();
  469. }
  470. #if !DEBUG && (SQLITE || POSTGRES || (MSSQL && !L2SQL))
  471. [Explicit]
  472. #endif
  473. [Test]
  474. public void G13_ProvidedAutoGeneratedColumn()
  475. {
  476. Northwind db = CreateDB();
  477. Category newCat = new Category();
  478. newCat.CategoryID = 999;
  479. newCat.CategoryName = "test";
  480. db.Categories.InsertOnSubmit(newCat);
  481. db.SubmitChanges();
  482. // CategoryID is [Column(AutoSync=AutoSync.OnInsert)], so it's
  483. // value is ignored on insert and will be updated
  484. Assert.AreNotEqual(999, newCat.CategoryID);
  485. // then, load our object
  486. var checkCat = (from c in db.Categories where c.CategoryID == newCat.CategoryID select c).Single();
  487. Assert.AreEqual(newCat.CategoryID, checkCat.CategoryID);
  488. // remove the whole thing
  489. db.Categories.DeleteOnSubmit(newCat);
  490. db.SubmitChanges();
  491. }
  492. [Test]
  493. public void G14_AutoGeneratedSupplierIdAndCompanyName()
  494. {
  495. Northwind db = CreateDB();
  496. Supplier supplier = new Supplier()
  497. {
  498. CompanyName = "Test Company",
  499. };
  500. db.Suppliers.InsertOnSubmit(supplier);
  501. db.SubmitChanges();
  502. Assert.IsNotNull(supplier.SupplierID);
  503. Assert.AreEqual("Test Company", supplier.CompanyName);
  504. db.Suppliers.DeleteOnSubmit(supplier);
  505. db.SubmitChanges();
  506. }
  507. [Test]
  508. [ExpectedException(typeof(InvalidOperationException))]
  509. public void G15_CustomerIdUpdate()
  510. {
  511. //if you run this against Microsoft Linq-to-Sql, it throws an InvalidOperationEx:
  512. //{"Value of member 'CustomerID' of an object of type 'Customers' changed.
  513. //A member defining the identity of the object cannot be changed.
  514. //Consider adding a new object with new identity and deleting the existing one instead."}
  515. Northwind db = CreateDB();
  516. Customer c1 = (from c in db.Customers
  517. where c.CustomerID == "AIRBU"
  518. select c).Single();
  519. c1.CustomerID = "TEMP";
  520. db.SubmitChanges();
  521. Customer c2 = (from c in db.Customers
  522. where c.CustomerID == "TEMP"
  523. select c).Single();
  524. c2.CustomerID = "AIRBU";
  525. db.SubmitChanges();
  526. }
  527. /// <summary>
  528. /// Quote from MSDN:
  529. /// If the object requested by the query is easily identifiable as one
  530. /// already retrieved, no query is executed. The identity table acts as a cache
  531. /// of all previously retrieved objects
  532. /// From Matt Warren: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=345635&SiteID=1
  533. /// The cache is checked when the query is a simple table.Where(pred) or table.First(pred) where the
  534. /// predicate refers only to the primary key. Otherwise the query is always sent and the cache only checked
  535. /// after the results are retrieved.
  536. /// The DLINQ cache is not distributed or shared, it is local and contained within the context. It is only a
  537. /// referential identity cache used to guarantee that two reads of the same entity return the same instance.
  538. /// You are not expected to hold the cache for an extended duration (except possibly for a client scenario),
  539. /// or share it across threads, processes, or machines in a cluster.
  540. /// </summary>
  541. #if !DEBUG && (SQLITE || POSTGRES || (MSSQL && !L2SQL))
  542. [Explicit]
  543. #endif
  544. [Test]
  545. public void G16_CustomerCacheHit()
  546. {
  547. Northwind db = CreateDB();
  548. Customer c1 = new Customer() { CustomerID = "temp", CompanyName = "Test", ContactName = "Test" };
  549. db.Customers.InsertOnSubmit(c1);
  550. db.SubmitChanges();
  551. db.ExecuteCommand("delete from \"Customers\" WHERE \"CustomerID\"='temp'");
  552. var res = db.Customers.First(c => c.CustomerID == "temp");
  553. Assert.IsNotNull(res);
  554. }
  555. #if !DEBUG && (SQLITE || POSTGRES || MSSQL)
  556. // L2SQL: System.InvalidOperationException : The type 'Test_NUnit_MsSql_Strict.WriteTest+OrderDetailWithSum' is not mapped as a Table.
  557. [Explicit]
  558. #endif
  559. [Test]
  560. public void G17_LocalPropertyUpdate()
  561. {
  562. Northwind dbo = CreateDB();
  563. NorthwindLocalProperty db = new NorthwindLocalProperty(dbo.Connection);
  564. var det = db.OrderDetailWithSums.First();
  565. det.ChangeQuantity();
  566. Assert.AreEqual(0, db.GetChangeSet().Updates.Count);
  567. db.SubmitChanges();
  568. }
  569. class NorthwindLocalProperty : Northwind
  570. {
  571. internal NorthwindLocalProperty(System.Data.IDbConnection connection)
  572. : base(connection) { }
  573. internal Table<OrderDetailWithSum> OrderDetailWithSums
  574. {
  575. get
  576. {
  577. return GetTable<OrderDetailWithSum>();
  578. }
  579. }
  580. }
  581. class OrderDetailWithSum : OrderDetail, INotifyPropertyChanged
  582. {
  583. public event PropertyChangedEventHandler PropertyChanged;
  584. protected virtual void OnPropertyChanged(string propertyName)
  585. {
  586. if (PropertyChanged != null)
  587. {
  588. PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  589. }
  590. }
  591. internal decimal? Sum
  592. {
  593. get
  594. {
  595. return Quantity * UnitPrice;
  596. }
  597. }
  598. internal void ChangeQuantity()
  599. {
  600. OnPropertyChanged("Sum");
  601. }
  602. }
  603. #if !DEBUG && (!(MSSQL && L2SQL))
  604. [Explicit]
  605. #endif
  606. // L2SQL: System.NotSupportedException : An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported.
  607. [Test]
  608. [ExpectedException(typeof(NotSupportedException))]
  609. public void G18_UpdateWithAttach()
  610. {
  611. List<Order> list;
  612. using (Northwind db = CreateDB())
  613. list = db.Orders.ToList();
  614. using (Northwind db = CreateDB())
  615. {
  616. var tbl = db.GetTable<Order>();
  617. foreach (var order in list)
  618. {
  619. if (order.Freight == null)
  620. continue;
  621. tbl.Attach(order);
  622. }
  623. db.SubmitChanges();
  624. }
  625. }
  626. #if !DEBUG && (SQLITE || POSTGRES || (MSSQL && !L2SQL))
  627. [Explicit]
  628. #endif
  629. [Test]
  630. public void G19_ExistingCustomerCacheHit()
  631. {
  632. Northwind db = CreateDB();
  633. string id = "ALFKI";
  634. Customer c1 = (from c in db.Customers
  635. where id == c.CustomerID
  636. select c).Single();
  637. db.Connection.ConnectionString = null;
  638. var x = db.Customers.First(c => id == c.CustomerID);
  639. }
  640. [Test]
  641. public void G20_CustomerCacheHitComparingToLocalVariable()
  642. {
  643. Northwind db = CreateDB();
  644. try
  645. {
  646. Customer c1 = new Customer() { CustomerID = "temp", CompanyName = "Test", ContactName = "Test" };
  647. db.Customers.InsertOnSubmit(c1);
  648. db.SubmitChanges();
  649. string id = "temp";
  650. var res = from c in db.Customers
  651. where c.CustomerID == id
  652. select c;
  653. Assert.AreEqual(1, res.Count(), "#1");
  654. db.ExecuteCommand("DELETE FROM \"Customers\" WHERE \"CustomerID\"='temp'");
  655. res = from c in db.Customers
  656. where c.CustomerID == id
  657. select c;
  658. Assert.AreEqual(0, res.Count(), "#2");
  659. }
  660. finally
  661. {
  662. db.ExecuteCommand("DELETE FROM \"Customers\" WHERE \"CustomerID\"='temp'");
  663. }
  664. }
  665. #endregion
  666. [Test]
  667. public void Update01()
  668. {
  669. var db = CreateDB();
  670. Employee p = db.Employees.First(r => r.LastName == "Fuller");
  671. DateTime beforeDateTime = p.BirthDate.Value;
  672. DateTime now = beforeDateTime.AddMinutes(10);
  673. p.BirthDate = now;
  674. db.SubmitChanges();
  675. Employee p2 = db.Employees.First(r => r.LastName == "Fuller");
  676. Assert.AreEqual(p2.BirthDate, now);
  677. //undo changes
  678. p.BirthDate = beforeDateTime;
  679. db.SubmitChanges();
  680. }
  681. #if !DEBUG && SQLITE
  682. [Explicit]
  683. #endif
  684. [Test]
  685. public void InsertAndDeleteWithDependencies()
  686. {
  687. const string newCategoryName = "temp Category";
  688. const string newProduct1 = "temp First Test Product";
  689. const string newProduct2 = "temp Second Test Product";
  690. var db = CreateDB();
  691. var product = new Product
  692. {
  693. #if INGRES
  694. Discontinued = "Y",
  695. #else
  696. Discontinued = true,
  697. #endif
  698. ProductName = newProduct1,
  699. };
  700. var category = new Category
  701. {
  702. CategoryName = newCategoryName,
  703. Description = "Insert Description Here",
  704. };
  705. category.Products.Add(product);
  706. Assert.AreEqual(0, category.CategoryID);
  707. Assert.AreEqual(0, product.CategoryID.Value);
  708. db.Categories.InsertOnSubmit(category);
  709. db.SubmitChanges();
  710. Assert.AreEqual(1, db.Categories.Where(c => c.CategoryName == newCategoryName).Count());
  711. Assert.AreNotEqual(0, category.CategoryID);
  712. Assert.AreEqual(1, db.Products.Where(p => p.ProductName == newProduct1).Count());
  713. Assert.AreEqual(category.CategoryID, product.CategoryID.Value);
  714. var p2 = new Product
  715. {
  716. #if INGRES
  717. Discontinued = "Y",
  718. #else
  719. Discontinued = true,
  720. #endif
  721. ProductName = newProduct2
  722. };
  723. category.Products.Add(p2);
  724. db.SubmitChanges();
  725. Assert.AreEqual(1, db.Products.Where(p => p.ProductName == newProduct2).Count());
  726. db.Products.DeleteOnSubmit(product);
  727. db.Products.DeleteOnSubmit(p2);
  728. db.Categories.DeleteOnSubmit(category);
  729. db.SubmitChanges();
  730. Assert.AreEqual(0, db.Categories.Where(c => c.CategoryName == newCategoryName).Count());
  731. Assert.AreEqual(0, db.Products.Where(p => p.ProductName == newProduct1).Count());
  732. Assert.AreEqual(0, db.Products.Where(p => p.ProductName == newProduct2).Count());
  733. }
  734. }
  735. }