1 using System.Collections.Generic; 2 using DomainObjects.Diagnostics; 3 using DomainObjects.Facade.Command; 4 using DomainObjects.Facade.Command.Function; 5 using DomainObjects.Facade.Test; 6 using DomainObjects.Test.Domain; 7 using NUnit.Framework; 8 9 namespace DomainObjects.Test.TestFixture 10 { 11 /// <summary> 12 /// Tests the UpdateByCriteria class. 13 /// </summary> 14 [TestFixture] 15 public class UpdateByCriteriaTests : DomainObjectsTestFixture 16 { 17 [Test] 18 public void ExecuteUpdate() 19 { 20 // Create and persist a set of products to set up the unit test. 21 // These products will be updated by criteria later in the test. 22 ProductCategory productCategory = new ProductCategory(GenerateUniqueString(Types.ProductCategory.Field._name), GenerateUniqueString(Types.ProductCategory.Field._description)).Manage<ProductCategory>(); 23 Product product1 = new Product(productCategory, GenerateUniqueString(Types.Product.Field._name)).Manage<Product>(); 24 Product product2 = new Product(productCategory, GenerateUniqueString(Types.Product.Field._name)).Manage<Product>(); 25 PersistenceFacade.Persist(product1, product2, productCategory); 26 27 // Create an update command 28 UpdateByCriteria updateByCriteria = new UpdateByCriteria(); 29 30 // Specify the field to be updated along with its new value 31 string updatedProductName = GenerateUniqueString(Types.Product.Field._name); 32 updateByCriteria.AddUpdateField(Types.Product.Field._name, updatedProductName); 33 34 // Specify which products will be updated. 35 // They each are associated with the same ProductCategory 36 // so use this to constrain the update. 37 updateByCriteria.Where.AddEqualTo(Types.Product.Field._productCategoryId, productCategory.PrimaryKey[0]); 38 39 // Execute the update 40 updateByCriteria.Execute<Product>(); 41 42 // Ensure that our assertions below are 43 // retrieving the values from the database 44 // and not the local caches 45 ClearAppDomainAndContextCache(); 46 47 // Validate that the products were updated with the new name. 48 Assert.AreEqual(updatedProductName, product1.Name, "The name of product1 was updated."); 49 Assert.AreEqual(updatedProductName, product2.Name, "The name of product2 was updated."); 50 } 51 52 /// <summary> 53 /// Validates that an 'UPDATE TOP()' clause is generated when <see cref="UpdateByCriteria.Top"/> is specified in an UpdateByCriteria command. 54 /// </summary> 55 [Test] 56 [Category(UnitTestCategory.DoesNotWorkWithOracle)] 57 public void ExecuteUpdateWithTop() 58 { 59 // Create and persist a set of products to set up the unit test. 60 // These products will be updated by criteria later in the test. 61 ProductCategory productCategory = new ProductCategory(GenerateUniqueString(Types.ProductCategory.Field._name), GenerateUniqueString(Types.ProductCategory.Field._description)).Manage<ProductCategory>(); 62 Product product1 = new Product(productCategory, GenerateUniqueString(Types.Product.Field._name)).Manage<Product>(); 63 Product product2 = new Product(productCategory, GenerateUniqueString(Types.Product.Field._name)).Manage<Product>(); 64 PersistenceFacade.Persist(product1, product2, productCategory); 65 66 // Create an update command 67 UpdateByCriteria updateByCriteria = new UpdateByCriteria(); 68 69 // Specify the field to be updated along with its new value 70 string updatedProductName = GenerateUniqueString(Types.Product.Field._name); 71 updateByCriteria.AddUpdateField(Types.Product.Field._name, updatedProductName); 72 73 // Specify which products will be updated. 74 // They each are associated with the same ProductCategory 75 // so use this to constrain the update. 76 updateByCriteria.Where.AddEqualTo(Types.Product.Field._productCategoryId, productCategory.PrimaryKey[0]); 77 78 // Specify that only the top 1 will be updated 79 updateByCriteria.Top = 1; 80 81 // Track the commands executed against the database 82 CommandMonitor commandMonitor = new CommandMonitor(); 83 84 // Execute the update 85 updateByCriteria.Execute<Product>(); 86 87 // Validate that the expected SQL statement was generated. 88 Assert.IsTrue(commandMonitor.FirstCommandText.Contains("UPDATE TOP (1)"), "AN 'UPDATE TOP()' SQL statement was generated."); 89 90 // Validate that only one product has the new name 91 Query<Product> productQuery = new Query<Product>(); 92 productQuery.Where.AddEqualTo(Types.Product.Field._name, updatedProductName); 93 List<Product> updatedProducts = productQuery.FindObjectSet(); 94 95 Assert.AreEqual(1, updatedProducts.Count, "Exactly one product was updated."); 96 97 // From the updateByCriteria statement, DomainObjects generates the following SQL UPDATE statement: 98 // 99 // UPDATE TOP (1) PRODUCT 100 // SET NAME = @PRODUCT01_NAME_1 101 // FROM PRODUCT AS PRODUCT01 102 // WHERE ((PRODUCT01.PRODUCT_CATEGORY_ID = @PRODUCT01_PRODUCT_CATEGORY_ID_0)) 103 } 104 105 /// <summary> 106 /// Validates that an assigned update value can be 107 /// a Case statement, and more generally, a Field. 108 /// </summary> 109 [Test] 110 public void UpdateByCriteriaWithCase() 111 { 112 // Create and persist a set of products to set up the unit test. 113 // These products will be updated by criteria later in the test. 114 ProductCategory productCategory = new ProductCategory(GenerateUniqueString(Types.ProductCategory.Field._name), GenerateUniqueString(Types.ProductCategory.Field._description)).Manage<ProductCategory>(); 115 116 string productName1 = GenerateUniqueString(Types.Product.Field._name); 117 Product product1 = new Product(productCategory, productName1).Manage<Product>(); 118 119 string productName2 = GenerateUniqueString(Types.Product.Field._name); 120 Product product2 = new Product(productCategory, productName2).Manage<Product>(); 121 PersistenceFacade.Persist(product1, product2, productCategory); 122 123 // Create an update command 124 UpdateByCriteria updateByCriteria = new UpdateByCriteria(); 125 126 // Specify the field to be updated along with its new value 127 string updatedProductName1 = GenerateUniqueString(Types.Product.Field._name); 128 string updatedProductName2 = GenerateUniqueString(Types.Product.Field._name); 129 130 // Build a Case clause 131 Case caseClause = new Case(); 132 Criteria when = new Criteria(); 133 when.AddEqualTo(Types.Product.Field._name, productName1); 134 caseClause.AddCase(when, updatedProductName1); 135 136 Criteria when2 = new Criteria(); 137 when2.AddEqualTo(Types.Product.Field._name, productName2); 138 caseClause.AddCase(when2, updatedProductName2); 139 140 updateByCriteria.AddUpdateField(Types.Product.Field._name, caseClause); 141 142 // Specify which products will be updated. 143 // They each are associated with the same ProductCategory 144 // so use this to constrain the update. 145 updateByCriteria.Where.AddEqualTo(Types.Product.Field._productCategoryId, productCategory.PrimaryKey[0]); 146 147 // Execute the update 148 updateByCriteria.Execute<Product>(); 149 150 // Ensure that our assertions below are 151 // retrieving the values from the database 152 // and not the local caches 153 ClearAppDomainAndContextCache(); 154 155 // Validate that the products were updated with the new name. 156 Assert.AreEqual(updatedProductName1, product1.Name, "The name of product1 was updated."); 157 Assert.AreEqual(updatedProductName2, product2.Name, "The name of product2 was updated."); 158 } 159 } 160 }