5 // Copyright (c) 2007-2008 Jiri Moudry, Pascal Craponne
\r
7 // Permission is hereby granted, free of charge, to any person obtaining a copy
\r
8 // of this software and associated documentation files (the "Software"), to deal
\r
9 // in the Software without restriction, including without limitation the rights
\r
10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
\r
11 // copies of the Software, and to permit persons to whom the Software is
\r
12 // furnished to do so, subject to the following conditions:
\r
14 // The above copyright notice and this permission notice shall be included in
\r
15 // all copies or substantial portions of the Software.
\r
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\r
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
\r
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
\r
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
\r
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
\r
28 using System.Collections.Generic;
\r
31 using System.Linq.Expressions;
\r
33 using NUnit.Framework;
\r
35 using System.ComponentModel;
\r
36 using System.Data.Linq.Mapping;
\r
41 using System.Data.Linq;
\r
43 using DbLinq.Data.Linq;
\r
47 using Id = System.Decimal;
\r
49 using Id = System.Int32;
\r
54 namespace Test_NUnit_MySql
\r
56 namespace Test_NUnit_OracleODP
\r
58 namespace Test_NUnit_Oracle
\r
60 namespace Test_NUnit_PostgreSql
\r
62 namespace Test_NUnit_Sqlite
\r
64 namespace Test_NUnit_Ingres
\r
65 #elif MSSQL && MONO_STRICT
\r
66 namespace Test_NUnit_MsSql_Strict
\r
68 namespace Test_NUnit_MsSql
\r
70 namespace Test_NUnit_Firebird
\r
74 public class WriteTestSetup : TestBase
\r
77 public void TestSetup()
\r
79 Northwind db = CreateDB();
\r
80 // "[Products]" gets converted to "Products".
\r
81 //This is a DbLinq-defined escape sequence, by Pascal.
\r
82 //db.ExecuteCommand("DELETE FROM [Products] WHERE [ProductName] like 'temp%'");
\r
84 var deleteProducts = db.Products.Where(p => p.ProductName.StartsWith("temp")).ToList();
\r
85 db.Products.DeleteAllOnSubmit(deleteProducts);
\r
87 var deleteCategories = db.Categories.Where(c => c.CategoryName.StartsWith("temp")).ToList();
\r
88 db.Categories.DeleteAllOnSubmit(deleteCategories);
\r
95 public class WriteTest : TestBase
\r
98 #region Tests 'E' test live object cache
\r
100 public void E1_LiveObjectsAreUnique()
\r
102 //grab an object twice, make sure we get the same object each time
\r
103 Northwind db = CreateDB();
\r
104 var q = from p in db.Products select p;
\r
105 Product pen1 = q.First();
\r
106 Product pen2 = q.First();
\r
107 string uniqueStr = "Unique" + Environment.TickCount;
\r
108 pen1.QuantityPerUnit = uniqueStr;
\r
109 bool isSameObject1 = pen2.QuantityPerUnit == uniqueStr;
\r
110 Assert.IsTrue(isSameObject1, "Expected pen1 and pen2 to be the same live object, but their fields are different");
\r
111 object oPen1 = pen1;
\r
112 object oPen2 = pen2;
\r
113 bool isSameObject2 = oPen1 == oPen2;
\r
114 Assert.IsTrue(isSameObject2, "Expected pen1 and pen2 to be the same live object, but their fields are different");
\r
118 public void E2_LiveObjectsAreUnique_Scalar()
\r
120 //grab an object twice, make sure we get the same object each time
\r
121 Northwind db = CreateDB();
\r
122 var q = from p in db.Products select p;
\r
123 Product pen1 = q.First(p => p.ProductName == "Pen");
\r
124 Product pen2 = q.Single(p => p.ProductName == "Pen");
\r
125 bool isSame = object.ReferenceEquals(pen1, pen2);
\r
126 Assert.IsTrue(isSame, "Expected pen1 and pen2 to be the same live object");
\r
129 #if MYSQL && USE_ALLTYPES
\r
131 public void E3_UpdateEnum()
\r
133 Northwind db = CreateDB();
\r
135 var q = from at in db.Alltypes where at.int_ == 1 select at;
\r
137 Alltype row = q.First();
\r
138 DbLinq_EnumTest newValue = row.DbLinq_EnumTest == DbLinq_EnumTest.BB
\r
139 ? DbLinq_EnumTest.CC
\r
140 : DbLinq_EnumTest.BB;
\r
142 row.DbLinq_EnumTest = newValue;
\r
144 db.SubmitChanges();
\r
150 #region Tests 'G' do insertion
\r
151 private int insertProduct_priv()
\r
153 Northwind db = CreateDB();
\r
155 Product newProd = new Product();
\r
156 newProd.CategoryID = db.Categories.First().CategoryID;
\r
157 newProd.ProductName = "Temp." + Environment.TickCount;
\r
158 newProd.QuantityPerUnit = "33 1/2";
\r
159 db.Products.InsertOnSubmit(newProd);
\r
160 db.SubmitChanges();
\r
161 Assert.Greater(newProd.ProductID, 0, "After insertion, ProductID should be non-zero");
\r
162 //Assert.IsFalse(newProd.IsModified, "After insertion, Product.IsModified should be false");
\r
163 return (int)newProd.ProductID; //this test cab be used from delete tests
\r
167 public void G1_InsertProduct()
\r
169 insertProduct_priv();
\r
173 public void G2_DeleteTest()
\r
175 int insertedID = insertProduct_priv();
\r
176 Assert.Greater(insertedID, 0, "DeleteTest cannot operate if row was not inserted");
\r
178 Northwind db = CreateDB();
\r
180 var q = from p in db.Products where p.ProductID == insertedID select p;
\r
181 List<Product> insertedProducts = q.ToList();
\r
182 foreach (Product insertedProd in insertedProducts)
\r
184 db.Products.DeleteOnSubmit(insertedProd);
\r
186 db.SubmitChanges();
\r
188 int numLeft = (from p in db.Products where p.ProductID == insertedID select p).Count();
\r
189 Assert.AreEqual(numLeft, 0, "After deletion, expected count of Products with ID=" + insertedID + " to be zero, instead got " + numLeft);
\r
193 public void G3_DeleteTest()
\r
195 int insertedID = insertProduct_priv();
\r
196 Assert.Greater(insertedID, 0, "DeleteTest cannot operate if row was not inserted");
\r
198 Northwind db = CreateDB();
\r
200 var q = from p in db.Products where p.ProductID == insertedID select p;
\r
201 List<Product> insertedProducts = q.ToList();
\r
202 foreach (Product insertedProd in insertedProducts)
\r
204 db.Products.DeleteOnSubmit(insertedProd);
\r
206 db.SubmitChanges();
\r
208 int numLeft = (from p in db.Products where p.ProductID == insertedID select p).Count();
\r
209 Assert.AreEqual(numLeft, 0, "After deletion, expected count of Products with ID=" + insertedID + " to be zero, instead got " + numLeft);
\r
213 public void G4_DuplicateSubmitTest()
\r
215 Northwind db = CreateDB();
\r
216 int productCount1 = db.Products.Count();
\r
217 #if INGRES && !MONO_STRICT
\r
218 Product p_temp = new Product { ProductName = "temp_g4", Discontinued = 0 };
\r
220 Product p_temp = new Product { ProductName = "temp_g4", Discontinued = false };
\r
222 db.Products.InsertOnSubmit(p_temp);
\r
223 db.SubmitChanges();
\r
224 db.SubmitChanges();
\r
225 int productCount2 = db.Products.Count();
\r
226 Assert.IsTrue(productCount2 == productCount1 + 1, "Expected product count to grow by one");
\r
230 /// there is a bug in v0.14 where fields cannot be updated to be null.
\r
233 public void G5_SetFieldToNull()
\r
235 string productName = "temp_G5_" + Environment.TickCount;
\r
236 Northwind db = CreateDB();
\r
239 Product p1 = new Product { ProductName = productName, Discontinued = false, UnitPrice = 11 };
\r
240 #elif INGRES && !MONO_STRICT
\r
241 Product p1 = new Product { ProductName = productName, Discontinued = 0, UnitPrice = 11m };
\r
243 Product p1 = new Product { ProductName = productName, Discontinued = false, UnitPrice = 11m };
\r
245 db.Products.InsertOnSubmit(p1);
\r
246 db.SubmitChanges();
\r
248 p1.UnitPrice = null;
\r
249 db.SubmitChanges();
\r
251 Northwind db3 = CreateDB();
\r
252 Product p3 = db3.Products.Single(p => p.ProductName == productName);
\r
253 Assert.IsNull(p3.UnitPrice);
\r
257 /// there is a bug in v0.14 where table Customers cannot be updated,
\r
258 /// because quotes where missing around the primaryKey in the UPDATE statement.
\r
261 public void G6_UpdateTableWithStringPK()
\r
263 Northwind db = CreateDB();
\r
264 Customer BT = db.Customers.Single(c => c.CustomerID == "BT___");
\r
265 BT.Country = "U.K.";
\r
266 db.SubmitChanges();
\r
270 public void G7_InsertTableWithStringPK()
\r
272 Northwind db = CreateDB();
\r
273 db.ExecuteCommand("DELETE FROM [Customers] WHERE [CustomerID]='TEMP_'");
\r
275 Customer custTemp = new Customer
\r
277 CustomerID = "TEMP_",
\r
278 CompanyName = "Magellan",
\r
279 ContactName = "Antonio Pigafetta",
\r
282 db.Customers.InsertOnSubmit(custTemp);
\r
283 db.SubmitChanges();
\r
287 public void G8_DeleteTableWithStringPK()
\r
289 Northwind db = CreateDB();
\r
290 Customer cust = (from c in db.Customers
\r
291 where c.CustomerID == "TEMP_"
\r
292 select c).Single();
\r
293 db.Customers.DeleteOnSubmit(cust);
\r
294 db.SubmitChanges();
\r
298 public void G9_UpdateOnlyChangedProperty()
\r
300 Northwind db = CreateDB();
\r
301 var cust = (from c in db.Customers
\r
305 CustomerID = c.CustomerID,
\r
310 var old = cust.City;
\r
311 cust.City = "Tallinn";
\r
312 db.SubmitChanges();
\r
313 db.SubmitChanges(); // A second call does not update anything
\r
316 //Npgsql.NpgsqlException was unhandled
\r
317 //Message="ERROR: 23502: null value in column \"companyname\" violates not-null constraint"
\r
319 db.SubmitChanges();
\r
325 public class Northwind1 : Northwind
\r
327 public Northwind1(System.Data.IDbConnection connection)
\r
328 : base(connection) { }
\r
330 [System.Data.Linq.Mapping.Table(Name = "cust1")]
\r
334 string _customerid;
\r
336 [System.Data.Linq.Mapping.Column(Storage = "_customerid",
\r
337 Name = "customerid", IsPrimaryKey = true,
\r
338 DbType = "char(10)",
\r
339 IsDbGenerated = true,
\r
340 Expression = "nextval('seq8')")]
\r
341 public string CustomerId
\r
343 get { return _customerid; }
\r
344 set { _customerid = value; }
\r
347 // Dummy property is required only as workaround over empty insert list bug
\r
348 // If this bug is fixed this may be removed
\r
350 [System.Data.Linq.Mapping.Column(Storage = "_dummy",
\r
351 DbType = "text", Name = "dummy")]
\r
352 public string Dummy
\r
360 public Table<Cust1> Cust1s
\r
365 return base.GetTable<Cust1>();
\r
371 public void G10_InsertCharSerialPrimaryKey()
\r
373 Northwind dbo = CreateDB();
\r
374 Northwind1 db = new Northwind1(dbo.Connection);
\r
378 @"create sequence seq8;
\r
379 create temp table cust1 ( CustomerID char(10) DEFAULT nextval('seq8'),
\r
384 Table<Northwind1.Cust1> cust1s =
\r
385 db.GetTable<Northwind1.Cust1>();
\r
387 var cust1 = new Northwind1.Cust1();
\r
389 db.Cust1s.InsertOnSubmit(cust1);
\r
390 db.SubmitChanges();
\r
391 Assert.IsNotNull(cust1.CustomerId);
\r
395 try { db.ExecuteCommand("drop table cust1;"); }
\r
397 try { db.ExecuteCommand("drop sequence seq8;"); }
\r
403 public class NorthwindG11 : Northwind
\r
405 public NorthwindG11(System.Data.IDbConnection connection)
\r
406 : base(connection) { }
\r
408 [Table(Name = "rid")]
\r
409 public class Rid : INotifyPropertyChanged
\r
414 protected int _reanr;
\r
418 [System.Data.Linq.Mapping.Column(Storage = "_id", Name = "id", DbType = "integer", IsPrimaryKey = true, IsDbGenerated = true, Expression = "next value for rid_id1_seq")]
\r
420 [System.Data.Linq.Mapping.Column(Storage = "_id", Name = "id", DbType = "integer", IsPrimaryKey = true, IsDbGenerated = true, Expression = "nextval('rid_id1_seq')")]
\r
424 get { return _id; }
\r
428 OnPropertyChanged("Id");
\r
433 [System.Data.Linq.Mapping.Column(Storage = "_reanr", Name = "reanr", DbType = "integer", IsDbGenerated = true, CanBeNull = false, Expression = "next value for rid_reanr_seq")]
\r
435 [System.Data.Linq.Mapping.Column(Storage = "_reanr", Name = "reanr", DbType = "integer", IsDbGenerated = true, CanBeNull = false, Expression = "nextval('rid_reanr_seq')")]
\r
439 get { return _reanr; }
\r
443 OnPropertyChanged("Reanr");
\r
448 #region INotifyPropertyChanged handling
\r
449 public event PropertyChangedEventHandler PropertyChanged;
\r
450 protected virtual void OnPropertyChanged(string propertyName)
\r
452 if (PropertyChanged != null)
\r
454 PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
\r
462 public Table<Rid> Rids
\r
466 return base.GetTable<Rid>();
\r
471 #if (POSTGRES || INGRES) && !MONO_STRICT
\r
474 public void G11_TwoSequencesInTable()
\r
476 Northwind dbo = CreateDB();
\r
477 NorthwindG11 db = new NorthwindG11(dbo.Connection);
\r
479 db.ExecuteCommand(@"create sequence rid_id1_seq");
\r
480 db.ExecuteCommand(@"create sequence rid_reanr_seq");
\r
482 db.ExecuteCommand(@"create table Rid ( id int primary key DEFAULT rid_id1_seq.nextval, reanr int DEFAULT rid_reanr_seq.nextval)");
\r
484 db.ExecuteCommand(@"create temp table Rid ( id int primary key DEFAULT nextval('rid_id1_seq'), reanr int DEFAULT nextval('rid_reanr_seq'))");
\r
486 DbLinq.Data.Linq.Table<NorthwindG11.Rid> Rids = db.GetTable<NorthwindG11.Rid>();
\r
488 var Rid = new NorthwindG11.Rid();
\r
490 Exception e = null;
\r
491 db.Rids.InsertOnSubmit(Rid);
\r
493 Rid = new NorthwindG11.Rid();
\r
495 db.Rids.InsertOnSubmit(Rid);
\r
498 db.SubmitChanges();
\r
500 catch (Exception ex)
\r
504 db.ExecuteCommand("drop table rid");
\r
505 db.ExecuteCommand("drop sequence rid_reanr_seq");
\r
506 db.ExecuteCommand("drop sequence rid_id1_seq");
\r
511 Assert.AreEqual(Rid.Id, 2);
\r
512 Assert.AreEqual(Rid.Reanr, 23);
\r
518 public void G12_EmptyInsertList()
\r
520 Northwind db = CreateDB();
\r
521 Region newRegion = new Region() { RegionDescription = "" }; // RegionDescription must be non-null
\r
522 db.Regions.InsertOnSubmit(newRegion);
\r
523 db.SubmitChanges();
\r
524 Assert.IsNotNull(newRegion.RegionID);
\r
525 db.Regions.DeleteOnSubmit(newRegion);
\r
526 db.SubmitChanges();
\r
530 public void G13_ProvidedAutoGeneratedColumn()
\r
532 Northwind db = CreateDB();
\r
533 Category newCat = new Category();
\r
534 newCat.CategoryID = 999;
\r
535 newCat.CategoryName = "test";
\r
536 db.Categories.InsertOnSubmit(newCat);
\r
537 db.SubmitChanges();
\r
538 Assert.AreEqual(999, newCat.CategoryID);
\r
539 // then, load our object
\r
540 var checkCat = (from c in db.Categories where c.CategoryID == newCat.CategoryID select c).Single();
\r
541 Assert.AreEqual(999, checkCat.CategoryID);
\r
542 // remove the whole thing
\r
543 db.Categories.DeleteOnSubmit(newCat);
\r
544 db.SubmitChanges();
\r
549 public void G14_AutoGeneratedSupplierIdAndCompanyName()
\r
551 Northwind db = CreateDB();
\r
552 Supplier supplier = new Supplier();
\r
553 db.Suppliers.InsertOnSubmit(supplier);
\r
554 db.SubmitChanges();
\r
555 Assert.IsNotNull(supplier.SupplierID);
\r
556 Assert.AreEqual(null, supplier.CompanyName);
\r
557 db.Suppliers.DeleteOnSubmit(supplier);
\r
558 db.SubmitChanges();
\r
563 [ExpectedException(typeof(InvalidOperationException))]
\r
564 public void G15_CustomerIdUpdate()
\r
566 //if you run this against Microsoft Linq-to-Sql, it throws an InvalidOperationEx:
\r
567 //{"Value of member 'CustomerID' of an object of type 'Customers' changed.
\r
568 //A member defining the identity of the object cannot be changed.
\r
569 //Consider adding a new object with new identity and deleting the existing one instead."}
\r
571 Northwind db = CreateDB();
\r
572 Customer c1 = (from c in db.Customers
\r
573 where c.CustomerID == "AIRBU"
\r
574 select c).Single();
\r
575 c1.CustomerID = "TEMP";
\r
576 db.SubmitChanges();
\r
577 Customer c2 = (from c in db.Customers
\r
578 where c.CustomerID == "TEMP"
\r
579 select c).Single();
\r
581 c2.CustomerID = "AIRBU";
\r
582 db.SubmitChanges();
\r
586 /// Quote from MSDN:
\r
587 /// If the object requested by the query is easily identifiable as one
\r
588 /// already retrieved, no query is executed. The identity table acts as a cache
\r
589 /// of all previously retrieved objects
\r
591 /// From Matt Warren: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=345635&SiteID=1
\r
592 /// The cache is checked when the query is a simple table.Where(pred) or table.First(pred) where the
\r
593 /// predicate refers only to the primary key. Otherwise the query is always sent and the cache only checked
\r
594 /// after the results are retrieved.
\r
595 /// The DLINQ cache is not distributed or shared, it is local and contained within the context. It is only a
\r
596 /// referential identity cache used to guarantee that two reads of the same entity return the same instance.
\r
597 /// You are not expected to hold the cache for an extended duration (except possibly for a client scenario),
\r
598 /// or share it across threads, processes, or machines in a cluster.
\r
601 public void G16_CustomerCacheHit()
\r
603 Northwind db = CreateDB();
\r
604 Customer c1 = new Customer() { CustomerID = "temp", CompanyName = "Test", ContactName = "Test" };
\r
605 db.Customers.InsertOnSubmit(c1);
\r
606 db.SubmitChanges();
\r
607 db.ExecuteCommand("delete from customers WHERE CustomerID='temp'");
\r
609 var res = (from c in db.Customers
\r
610 where c.CustomerID == "temp"
\r
611 select c).Single();
\r
617 public void G17_LocalPropertyUpdate()
\r
619 Northwind dbo = CreateDB();
\r
620 NorthwindLocalProperty db = new NorthwindLocalProperty(dbo.Connection);
\r
621 var det = db.OrderDetailWithSums.First();
\r
622 det.ChangeQuantity();
\r
623 Assert.AreEqual(0, db.GetChangeSet().Updates.Count);
\r
624 db.SubmitChanges();
\r
628 class NorthwindLocalProperty : Northwind
\r
630 internal NorthwindLocalProperty(System.Data.IDbConnection connection)
\r
631 : base(connection) { }
\r
633 internal Table<OrderDetailWithSum> OrderDetailWithSums
\r
637 return GetTable<OrderDetailWithSum>();
\r
643 class OrderDetailWithSum : OrderDetail, INotifyPropertyChanged
\r
645 public event PropertyChangedEventHandler PropertyChanged;
\r
646 protected virtual void OnPropertyChanged(string propertyName)
\r
648 if (PropertyChanged != null)
\r
650 PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
\r
654 internal decimal? Sum
\r
658 return Quantity * UnitPrice;
\r
662 internal void ChangeQuantity()
\r
664 OnPropertyChanged("Sum");
\r
670 public void G18_UpdateWithAttach()
\r
673 using (Northwind db = CreateDB())
\r
674 list = db.Orders.ToList();
\r
676 using (Northwind db = CreateDB())
\r
678 var tbl = db.GetTable<Order>();
\r
679 foreach (var order in list)
\r
681 if (order.Freight == null)
\r
684 order.Freight += 1;
\r
686 db.SubmitChanges();
\r
689 using (Northwind db = CreateDB())
\r
691 var tbl = db.GetTable<Order>();
\r
692 foreach (var order in list)
\r
694 if (order.Freight == null)
\r
697 order.Freight -= 1;
\r
699 db.SubmitChanges();
\r
705 public void G19_ExistingCustomerCacheHit()
\r
707 Northwind db = CreateDB();
\r
708 string id = "AIRBU";
\r
709 Customer c1 = (from c in db.Customers
\r
710 where id == c.CustomerID
\r
711 select c).Single();
\r
713 db.Connection.ConnectionString = null;
\r
715 var x = db.Customers.Single(c => id == c.CustomerID);
\r
720 public void G20_CustomerCacheHitComparingToLocalVariable()
\r
722 Northwind db = CreateDB();
\r
725 Customer c1 = new Customer() { CustomerID = "temp", CompanyName = "Test", ContactName = "Test" };
\r
726 db.Customers.InsertOnSubmit(c1);
\r
727 db.SubmitChanges();
\r
729 string id = "temp";
\r
730 var res = from c in db.Customers
\r
731 where c.CustomerID == id
\r
734 Assert.AreEqual(1, res.Count(), "#1");
\r
736 db.ExecuteCommand("delete from customers WHERE CustomerID='temp'");
\r
738 res = from c in db.Customers
\r
739 where c.CustomerID == id
\r
741 Assert.AreEqual(0, res.Count(), "#2");
\r
745 db.ExecuteCommand("delete from customers WHERE CustomerID='temp'");
\r
753 public void Update01()
\r
755 var db = CreateDB();
\r
756 Employee p = db.Employees.First(r => r.LastName == "Fuller");
\r
758 DateTime beforeDateTime = p.BirthDate.Value;
\r
759 DateTime now = beforeDateTime.AddMinutes(10);
\r
762 db.SubmitChanges();
\r
764 Employee p2 = db.Employees.First(r => r.LastName == "Fuller");
\r
765 Assert.AreEqual(p2.BirthDate, now);
\r
768 p.BirthDate = beforeDateTime;
\r
769 db.SubmitChanges();
\r
773 public void InsertAndDeleteWithDependencies()
\r
775 const string newCategoryName = "temp Category";
\r
776 const string newProduct1 = "temp First Test Product";
\r
777 const string newProduct2 = "temp Second Test Product";
\r
779 var db = CreateDB();
\r
781 var product = new Product
\r
783 Discontinued = true,
\r
784 ProductName = newProduct1,
\r
787 var category = new Category
\r
789 CategoryName = newCategoryName,
\r
790 Description = "Insert Description Here",
\r
792 category.Products.Add(product);
\r
794 Assert.AreEqual(0, category.CategoryID);
\r
795 Assert.AreEqual(0, product.CategoryID.Value);
\r
797 db.Categories.InsertOnSubmit(category);
\r
798 db.SubmitChanges();
\r
800 Assert.AreEqual(1, db.Categories.Where(c => c.CategoryName == newCategoryName).Count());
\r
801 Assert.AreNotEqual(0, category.CategoryID);
\r
802 Assert.AreEqual(1, db.Products.Where(p => p.ProductName == newProduct1).Count());
\r
803 Assert.AreEqual(category.CategoryID, product.CategoryID.Value);
\r
805 var p2 = new Product
\r
807 Discontinued = true,
\r
808 ProductName = newProduct2
\r
810 category.Products.Add(p2);
\r
811 db.SubmitChanges();
\r
813 Assert.AreEqual(1, db.Products.Where(p => p.ProductName == newProduct2).Count());
\r
815 db.Products.DeleteOnSubmit(product);
\r
816 db.Products.DeleteOnSubmit(p2);
\r
817 db.Categories.DeleteOnSubmit(category);
\r
818 db.SubmitChanges();
\r
820 Assert.AreEqual(0, db.Categories.Where(c => c.CategoryName == newCategoryName).Count());
\r
821 Assert.AreEqual(0, db.Products.Where(p => p.ProductName == newProduct1).Count());
\r
822 Assert.AreEqual(0, db.Products.Where(p => p.ProductName == newProduct2).Count());
\r