示例#1
0
        public void InferredAddThenAttach_EntityCollection()
        {
            NorthwindEntityContainer ec = new NorthwindEntityContainer();

            // track changes on products
            int productAdded                = 0;
            int productRemoved              = 0;
            int productPropertyChanged      = 0;
            int productsCollectionChanged   = 0;
            EntitySet <Product> productsSet = ec.GetEntitySet <Product>();

            productsSet.EntityAdded     += (obj, args) => productAdded += 1;
            productsSet.EntityRemoved   += (obj, args) => productRemoved += 1;
            productsSet.PropertyChanged += (obj, args) => productPropertyChanged += 1;
            ((INotifyCollectionChanged)productsSet).CollectionChanged += (obj, args) =>
                                                                         productsCollectionChanged += 1;

            // create and add order to container
            Order order = new Order
            {
                OrderID = 1
            };

            ec.LoadEntities(new Entity[] { order });
            ((IChangeTracking)ec).AcceptChanges();

            // build a detached graph of a detail and product
            Order_Detail detail = new Order_Detail
            {
                OrderID   = 1,
                ProductID = 2
            };
            Product product = new Product
            {
                ProductID = 3
            };

            detail.Product = product;

            // Add detached detail to attached order.
            // Product is now tracked since it is an 'inferred' entity
            order.Order_Details.Add(detail);
            Assert.IsTrue(product.IsInferred);
            Assert.AreEqual(1, productAdded);
            Assert.AreEqual(0, productRemoved);
            Assert.AreEqual(2, productPropertyChanged);
            Assert.AreEqual(1, productsCollectionChanged);

            // now explicitly attach product
            productsSet.Attach(product);

            // should not have duplicate refernce to product
            Assert.AreEqual(1, productsSet.Count);

            // should not raise events since product was already added
            Assert.AreEqual(1, productAdded);
            Assert.AreEqual(0, productRemoved);
            Assert.AreEqual(2, productPropertyChanged);
            Assert.AreEqual(1, productsCollectionChanged);
        }
示例#2
0
        public void IdentityCacheCleanup()
        {
            NorthwindEntityContainer ec = new NorthwindEntityContainer();

            ec.LoadEntities(new Entity[] { new Product {
                                               ProductID = 1
                                           }, new Product {
                                               ProductID = 2
                                           }, new Product {
                                               ProductID = 3
                                           } });
            EntitySet <Product> productSet = ec.GetEntitySet <Product>();

            // Delete an entity
            Product prod = productSet.First();
            int     key  = prod.ProductID;

            productSet.Remove(prod);
            ((IChangeTracking)ec).AcceptChanges();
            // After the delete, the entity is moved back into the default state
            Assert.AreEqual(EntityState.Detached, prod.EntityState);

            // After it has been deleted, we should be able to add
            // a new entity with the same key
            Product newProduct = new Product
            {
                ProductID = key
            };

            productSet.Add(newProduct);
            Assert.AreEqual(EntityState.New, newProduct.EntityState);
            ((IChangeTracking)ec).AcceptChanges();
            Product requeriedProduct = productSet.Single(p => p.ProductID == key);

            Assert.AreSame(newProduct, requeriedProduct);  // make sure instances are same

            // Bug 526544 repro case - delete and submit, then attempt
            // to re-add
            prod = productSet.First();
            key  = prod.ProductID;
            productSet.Remove(prod);
            ((IChangeTracking)ec).AcceptChanges();
            productSet.Add(prod);
            Assert.AreEqual(EntityState.New, prod.EntityState);
            ((IChangeTracking)ec).AcceptChanges();

            // verify that when an entity is Detached, it is removed from ID cache
            // after the detach, attaching an entity with the same key should succeed
            prod = productSet.First();
            key  = prod.ProductID;
            productSet.Detach(prod);
            newProduct = new Product
            {
                ProductID = key
            };
            productSet.Attach(newProduct);
            requeriedProduct = productSet.Single(p => p.ProductID == key);
            Assert.AreSame(newProduct, requeriedProduct);  // make sure instances are same
        }
示例#3
0
        public void InferredAdd_EntityRefs()
        {
            NorthwindEntityContainer ec = new NorthwindEntityContainer();

            // add a few existing entities
            Order order1 = new Order
            {
                OrderID = 1
            };
            Order_Detail detail1 = new Order_Detail
            {
                OrderID = 2, ProductID = 1
            };

            ec.LoadEntities(new Entity[] { order1, detail1 });
            ((IChangeTracking)ec).AcceptChanges();
            Assert.IsFalse(ec.HasChanges);

            // build a detached graph of a new category and 2 products
            Category newCategory = new Category
            {
                CategoryID = 1
            };
            Product newProduct1 = new Product
            {
                ProductID = 3
            };
            Product newProduct2 = new Product
            {
                ProductID = 4
            };

            newCategory.Products.Add(newProduct1);
            newCategory.Products.Add(newProduct2);

            // set the the Product reference on the existing detail to
            // one of the new detached products - we expect the entire
            // graph to be infer added
            EntityChangeSet cs = ec.GetChanges();

            Assert.IsTrue(cs.IsEmpty);
            detail1.Product = newProduct1;
            cs = ec.GetChanges();
            Assert.AreEqual(3, cs.AddedEntities.Count);
            Assert.IsTrue(cs.AddedEntities.Contains(newProduct1)); // the entity set directly
            Assert.IsTrue(cs.AddedEntities.Contains(newCategory)); // inferred via Product.Category ER
            Assert.IsTrue(cs.AddedEntities.Contains(newProduct2)); // inferred via Category.Products EC

            // verify that inferred Adds can be state transitioned via subsequent
            // calls to Attach
            ec.GetEntitySet <Product>().Attach(newProduct2);
            newProduct2.ProductName += "x";
            cs = ec.GetChanges();
            Assert.AreEqual(2, cs.AddedEntities.Count);
            Assert.AreEqual(2, cs.ModifiedEntities.Count);
            Assert.IsFalse(cs.AddedEntities.Contains(newProduct2));
            Assert.IsTrue(cs.ModifiedEntities.Contains(newProduct2));
        }
示例#4
0
        public void TestAssociations_UpdatedReferencingNew()
        {
            NorthwindEntityContainer ec = new NorthwindEntityContainer();
            Product p1 = new Product {
                ProductID = 1, CategoryID = 1
            };
            Product p2 = new Product {
                ProductID = 2, CategoryID = 2
            };
            Category c1 = new Category {
                CategoryID = 1
            };
            Category c2 = new Category {
                CategoryID = 2
            };

            ec.LoadEntities(new Entity[] { p1, p2, c1, c2 });

            // take two existing parents (the FK side of the association)
            // access their existing children
            Category prevCat = p1.Category;

            Assert.IsNotNull(prevCat);
            prevCat = p2.Category;
            Assert.IsNotNull(prevCat);

            // create two new children
            Category newCat1 = new Category {
                CategoryID = 3
            };
            Category newCat2 = new Category {
                CategoryID = 4
            };

            // assign the two new children
            p1.Category = newCat1;
            p2.Category = newCat2;

            EntityChangeSet cs = ec.GetChanges();

            Assert.AreEqual(2, cs.AddedEntities.Count);
            Assert.AreEqual(2, cs.ModifiedEntities.Count);

            List <ChangeSetEntry> entries = ChangeSetBuilder.Build(cs);
            ChangeSetEntry        entry   = entries.Single(p => p.Entity == p1);

            // the bug was that we weren't populating the association map in this
            // scenario since previously we required BOTH parent and child to be new.
            // We've relaxed that to ensure that if the child is new, the association
            // shows up in the map.
            Assert.IsNotNull(entry.Associations);
            int[]    ids        = entry.Associations["Category"];
            Category referenced = (Category)entries.Single(p => p.Id == ids.Single()).Entity;

            Assert.AreSame(newCat1, referenced);
        }
示例#5
0
        public void ChangeSet_DontLoadUnloadedAssociations()
        {
            NorthwindEntityContainer entities = new NorthwindEntityContainer();
            EntitySet <Order>        orders   = entities.GetEntitySet <Order>();
            EntitySet <Order_Detail> details  = entities.GetEntitySet <Order_Detail>();

            // add a few existing entities
            Order order = new Order
            {
                OrderID = 1
            };
            Order_Detail detail = new Order_Detail
            {
                OrderID = 1, ProductID = 1
            };

            entities.LoadEntities(new Entity[] { order, detail });

            // modify both entities
            order.Freight   = 5;
            detail.Quantity = 5;

            IEntityRef er = detail.GetEntityRef("Order");

            Assert.IsNull(er);
            IEntityCollection ec = order.Order_Details;

            Assert.IsFalse(ec.HasValues);

            EntityChangeSet cs = entities.GetChanges();

            Assert.AreEqual(2, cs.ModifiedEntities.Count);

            // after computing the changeset, no association members
            // should have been loaded
            er = detail.GetEntityRef("Order");
            Assert.IsNull(er);
            Assert.IsFalse(ec.HasValues);

            // after building the operation list, no association members
            // should have been loaded
            ChangeSetBuilder.Build(cs);
            er = detail.GetEntityRef("Order");
            Assert.IsNull(er);
            Assert.IsFalse(ec.HasValues);
        }
        public void ChangeSet_DontLoadUnloadedAssociations()
        {
            NorthwindEntityContainer entities = new NorthwindEntityContainer();
            EntitySet<Order> orders = entities.GetEntitySet<Order>();
            EntitySet<Order_Detail> details = entities.GetEntitySet<Order_Detail>();

            // add a few existing entities
            Order order = new Order
            {
                OrderID = 1
            };
            Order_Detail detail = new Order_Detail
            {
                OrderID = 1, ProductID = 1
            };
            entities.LoadEntities(new Entity[] { order, detail });

            // modify both entities
            order.Freight = 5;
            detail.Quantity = 5;

            IEntityRef er = detail.GetEntityRef("Order");
            Assert.IsNull(er);
            IEntityCollection ec = order.Order_Details;
            Assert.IsFalse(ec.HasValues);

            EntityChangeSet cs = entities.GetChanges();
            Assert.AreEqual(2, cs.ModifiedEntities.Count);

            // after computing the changeset, no association members
            // should have been loaded
            er = detail.GetEntityRef("Order");
            Assert.IsNull(er);
            Assert.IsFalse(ec.HasValues);

            // after building the operation list, no association members
            // should have been loaded
            ChangeSetBuilder.Build(cs);
            er = detail.GetEntityRef("Order");
            Assert.IsNull(er);
            Assert.IsFalse(ec.HasValues);
        }
        public void TestAssociations_UpdatedReferencingNew()
        {
            NorthwindEntityContainer ec = new NorthwindEntityContainer();
            Product p1 = new Product { ProductID = 1, CategoryID = 1 };
            Product p2 = new Product { ProductID = 2, CategoryID = 2 };
            Category c1 = new Category { CategoryID = 1 };
            Category c2 = new Category { CategoryID = 2 };
            ec.LoadEntities(new Entity[] { p1, p2, c1, c2 });

            // take two existing parents (the FK side of the association)
            // access their existing children
            Category prevCat = p1.Category;
            Assert.IsNotNull(prevCat);
            prevCat = p2.Category;
            Assert.IsNotNull(prevCat);

            // create two new children
            Category newCat1 = new Category { CategoryID = 3 };
            Category newCat2 = new Category { CategoryID = 4 };

            // assign the two new children
            p1.Category = newCat1;
            p2.Category = newCat2;

            EntityChangeSet cs = ec.GetChanges();
            Assert.AreEqual(2, cs.AddedEntities.Count);
            Assert.AreEqual(2, cs.ModifiedEntities.Count);

            List<ChangeSetEntry> entries = ChangeSetBuilder.Build(cs);
            ChangeSetEntry entry = entries.Single(p => p.Entity == p1);

            // the bug was that we weren't populating the association map in this
            // scenario since previously we required BOTH parent and child to be new.
            // We've relaxed that to ensure that if the child is new, the association
            // shows up in the map.
            Assert.IsNotNull(entry.Associations);
            int[] ids = entry.Associations["Category"];
            Category referenced = (Category)entries.Single(p => p.Id == ids.Single()).Entity;
            Assert.AreSame(newCat1, referenced);
        }
        public void TestAssociations_GraphDelete()
        {
            NorthwindEntityContainer entities = new NorthwindEntityContainer();

            #region Create a test graph
            Customer cust = new Customer
            {
                CustomerID = "ALFKI"
            };
            Order order = new Order
            {
                OrderID = 1
            };
            order.Customer = cust;
            order.Order_Details.Add(new Order_Detail
            {
                ProductID = 1
            });
            order.Order_Details.Add(new Order_Detail
            {
                ProductID = 2
            });
            order.Order_Details.Add(new Order_Detail
            {
                ProductID = 3
            });

            entities.LoadEntities(new Entity[] { cust, order });
            entities.LoadEntities(order.Order_Details);
            ((IRevertibleChangeTracking)entities).AcceptChanges();
            #endregion

            // now delete the graph
            // TODO : currently this has to be done in this specific order
            // with association modifications being done while the parent
            // is attached (before it is removed from set)
            foreach (Order_Detail detail in order.Order_Details)
            {
                order.Order_Details.Remove(detail);
                entities.GetEntitySet<Order_Detail>().Remove(detail);
            }
            cust.Orders.Remove(order);
            entities.GetEntitySet<Order>().Remove(order);
            entities.GetEntitySet<Customer>().Remove(cust);

            // verify the changeset
            EntityChangeSet changeSet = entities.GetChanges();
            Assert.AreEqual(5, changeSet.RemovedEntities.Count);

            // build the operation list and verify it
            List<ChangeSetEntry> operations = ChangeSetBuilder.Build(changeSet);

            // verify that the association collections for the Order operation are null
            ChangeSetEntry orderOperation = operations.Single(p => p.Entity == order);
            ChangeSetEntry custOperation = operations.Single(p => p.Entity == cust);
            Assert.IsNull(orderOperation.Associations);
            Assert.IsNull(orderOperation.OriginalAssociations);
            Assert.IsNotNull(orderOperation.OriginalEntity);
            
            // verify that the association collections for the Customer operation are null
            Assert.IsNull(custOperation.OriginalEntity);
            Assert.IsNull(custOperation.Associations);
            Assert.IsNull(custOperation.OriginalAssociations);

            // verify that deleted OrderDetails have null associations as well
            ChangeSetEntry detailOperation = operations.First(p => p.Entity.GetType() == typeof(Order_Detail));
            Assert.IsNotNull(detailOperation.OriginalEntity);
            Assert.IsNull(detailOperation.Associations);
            Assert.IsNull(detailOperation.OriginalAssociations);
        }
        public void IdentityCacheCleanup()
        {
            NorthwindEntityContainer ec = new NorthwindEntityContainer();
            ec.LoadEntities(new Entity[] { new Product { ProductID = 1 }, new Product { ProductID = 2 }, new Product { ProductID = 3 } });
            EntitySet<Product> productSet = ec.GetEntitySet<Product>();

            // Delete an entity
            Product prod = productSet.First();
            int key = prod.ProductID;
            productSet.Remove(prod);
            ((IChangeTracking)ec).AcceptChanges();
            // After the delete, the entity is moved back into the default state
            Assert.AreEqual(EntityState.Detached, prod.EntityState);

            // After it has been deleted, we should be able to add
            // a new entity with the same key
            Product newProduct = new Product
            {
                ProductID = key
            };
            productSet.Add(newProduct);
            Assert.AreEqual(EntityState.New, newProduct.EntityState);
            ((IChangeTracking)ec).AcceptChanges();
            Product requeriedProduct = productSet.Single(p => p.ProductID == key);
            Assert.AreSame(newProduct, requeriedProduct);  // make sure instances are same

            // Bug 526544 repro case - delete and submit, then attempt
            // to re-add
            prod = productSet.First();
            key = prod.ProductID;
            productSet.Remove(prod);
            ((IChangeTracking)ec).AcceptChanges();
            productSet.Add(prod);
            Assert.AreEqual(EntityState.New, prod.EntityState);
            ((IChangeTracking)ec).AcceptChanges();

            // verify that when an entity is Detached, it is removed from ID cache
            // after the detach, attaching an entity with the same key should succeed
            prod = productSet.First();
            key = prod.ProductID;
            productSet.Detach(prod);
            newProduct = new Product
            {
                ProductID = key
            };
            productSet.Attach(newProduct);
            requeriedProduct = productSet.Single(p => p.ProductID == key);
            Assert.AreSame(newProduct, requeriedProduct);  // make sure instances are same
        }
        public void InferredAdd_EntityRefs()
        {
            NorthwindEntityContainer ec = new NorthwindEntityContainer();

            // add a few existing entities
            Order order1 = new Order
            {
                OrderID = 1
            };
            Order_Detail detail1 = new Order_Detail
            {
                OrderID = 2, ProductID = 1
            };
            ec.LoadEntities(new Entity[] { order1, detail1 });
            ((IChangeTracking)ec).AcceptChanges();
            Assert.IsFalse(ec.HasChanges);

            // build a detached graph of a new category and 2 products
            Category newCategory = new Category
            {
                CategoryID = 1
            };
            Product newProduct1 = new Product
            {
                ProductID = 3
            };
            Product newProduct2 = new Product
            {
                ProductID = 4
            };
            newCategory.Products.Add(newProduct1);
            newCategory.Products.Add(newProduct2);

            // set the the Product reference on the existing detail to
            // one of the new detached products - we expect the entire
            // graph to be infer added
            EntityChangeSet cs = ec.GetChanges();
            Assert.IsTrue(cs.IsEmpty);
            detail1.Product = newProduct1;
            cs = ec.GetChanges();
            Assert.AreEqual(3, cs.AddedEntities.Count);
            Assert.IsTrue(cs.AddedEntities.Contains(newProduct1)); // the entity set directly
            Assert.IsTrue(cs.AddedEntities.Contains(newCategory)); // inferred via Product.Category ER
            Assert.IsTrue(cs.AddedEntities.Contains(newProduct2)); // inferred via Category.Products EC

            // verify that inferred Adds can be state transitioned via subsequent
            // calls to Attach
            ec.GetEntitySet<Product>().Attach(newProduct2);
            newProduct2.ProductName += "x";
            cs = ec.GetChanges();
            Assert.AreEqual(2, cs.AddedEntities.Count);
            Assert.AreEqual(2, cs.ModifiedEntities.Count);
            Assert.IsFalse(cs.AddedEntities.Contains(newProduct2));
            Assert.IsTrue(cs.ModifiedEntities.Contains(newProduct2));
        }
        public void InferredAdd_EntityCollection()
        {
            NorthwindEntityContainer ec = new NorthwindEntityContainer();

            // add a few existing entities
            Order order1 = new Order
            {
                OrderID = 1
            };
            Order order2 = new Order
            {
                OrderID = 2
            };
            Order_Detail detail1 = new Order_Detail
            {
                OrderID = 2, ProductID = 1
            };
            ec.LoadEntities(new Entity[] { order1, order2, detail1 });
            ((IChangeTracking)ec).AcceptChanges();
            Assert.IsFalse(ec.HasChanges);

            // build a detached graph of a new category and 2 products,
            // referenced by a detail
            Order_Detail newDetail1 = new Order_Detail
            {
                OrderID = 1, ProductID = 2
            };
            Category newCategory = new Category
            {
                CategoryID = 1
            };
            Product newProduct1 = new Product
            {
                ProductID = 3
            };
            Product newProduct2 = new Product
            {
                ProductID = 4
            };
            newCategory.Products.Add(newProduct1);
            newCategory.Products.Add(newProduct2);
            newDetail1.Product = newProduct1;

            EntityChangeSet cs = ec.GetChanges();
            Assert.IsTrue(cs.IsEmpty);

            // verify that adding an unattached entity to an EC results in
            // the expected inferred Adds
            order1.Order_Details.Add(newDetail1);
            cs = ec.GetChanges();
            Assert.AreEqual(4, cs.AddedEntities.Count);
            Assert.IsTrue(cs.AddedEntities.Contains(newDetail1));  // the entity added directly
            Assert.IsTrue(cs.AddedEntities.Contains(newProduct1)); // inferred via Detail.Product ER
            Assert.IsTrue(cs.AddedEntities.Contains(newCategory)); // inferred via Product.Category ER
            Assert.IsTrue(cs.AddedEntities.Contains(newProduct2)); // inferred via Category.Products EC

            // verify that inferred Adds can be state transitioned via subsequent
            // calls to Attach
            ec.GetEntitySet<Product>().Attach(newProduct2);
            newProduct2.ProductName += "x";
            cs = ec.GetChanges();
            Assert.AreEqual(3, cs.AddedEntities.Count);
            Assert.AreEqual(1, cs.ModifiedEntities.Count);
            Assert.IsFalse(cs.AddedEntities.Contains(newProduct2));
            Assert.IsTrue(cs.ModifiedEntities.Contains(newProduct2));
        }
示例#12
0
        public void TestAssociations_GraphDelete()
        {
            NorthwindEntityContainer entities = new NorthwindEntityContainer();

            #region Create a test graph
            Customer cust = new Customer
            {
                CustomerID = "ALFKI"
            };
            Order order = new Order
            {
                OrderID = 1
            };
            order.Customer = cust;
            order.Order_Details.Add(new Order_Detail
            {
                ProductID = 1
            });
            order.Order_Details.Add(new Order_Detail
            {
                ProductID = 2
            });
            order.Order_Details.Add(new Order_Detail
            {
                ProductID = 3
            });

            entities.LoadEntities(new Entity[] { cust, order });
            entities.LoadEntities(order.Order_Details);
            ((IRevertibleChangeTracking)entities).AcceptChanges();
            #endregion

            // now delete the graph
            // TODO : currently this has to be done in this specific order
            // with association modifications being done while the parent
            // is attached (before it is removed from set)
            foreach (Order_Detail detail in order.Order_Details)
            {
                order.Order_Details.Remove(detail);
                entities.GetEntitySet <Order_Detail>().Remove(detail);
            }
            cust.Orders.Remove(order);
            entities.GetEntitySet <Order>().Remove(order);
            entities.GetEntitySet <Customer>().Remove(cust);

            // verify the changeset
            EntityChangeSet changeSet = entities.GetChanges();
            Assert.AreEqual(5, changeSet.RemovedEntities.Count);

            // build the operation list and verify it
            List <ChangeSetEntry> operations = ChangeSetBuilder.Build(changeSet);

            // verify that the association collections for the Order operation are null
            ChangeSetEntry orderOperation = operations.Single(p => p.Entity == order);
            ChangeSetEntry custOperation  = operations.Single(p => p.Entity == cust);
            Assert.IsNull(orderOperation.Associations);
            Assert.IsNull(orderOperation.OriginalAssociations);
            Assert.IsNotNull(orderOperation.OriginalEntity);

            // verify that the association collections for the Customer operation are null
            Assert.IsNull(custOperation.OriginalEntity);
            Assert.IsNull(custOperation.Associations);
            Assert.IsNull(custOperation.OriginalAssociations);

            // verify that deleted OrderDetails have null associations as well
            ChangeSetEntry detailOperation = operations.First(p => p.Entity.GetType() == typeof(Order_Detail));
            Assert.IsNotNull(detailOperation.OriginalEntity);
            Assert.IsNull(detailOperation.Associations);
            Assert.IsNull(detailOperation.OriginalAssociations);
        }
示例#13
0
        public void InferredAdd_EntityCollection()
        {
            NorthwindEntityContainer ec = new NorthwindEntityContainer();

            // add a few existing entities
            Order order1 = new Order
            {
                OrderID = 1
            };
            Order order2 = new Order
            {
                OrderID = 2
            };
            Order_Detail detail1 = new Order_Detail
            {
                OrderID = 2, ProductID = 1
            };

            ec.LoadEntities(new Entity[] { order1, order2, detail1 });
            ((IChangeTracking)ec).AcceptChanges();
            Assert.IsFalse(ec.HasChanges);

            // build a detached graph of a new category and 2 products,
            // referenced by a detail
            Order_Detail newDetail1 = new Order_Detail
            {
                OrderID = 1, ProductID = 2
            };
            Category newCategory = new Category
            {
                CategoryID = 1
            };
            Product newProduct1 = new Product
            {
                ProductID = 3
            };
            Product newProduct2 = new Product
            {
                ProductID = 4
            };

            newCategory.Products.Add(newProduct1);
            newCategory.Products.Add(newProduct2);
            newDetail1.Product = newProduct1;

            EntityChangeSet cs = ec.GetChanges();

            Assert.IsTrue(cs.IsEmpty);

            // verify that adding an unattached entity to an EC results in
            // the expected inferred Adds
            order1.Order_Details.Add(newDetail1);
            cs = ec.GetChanges();
            Assert.AreEqual(4, cs.AddedEntities.Count);
            Assert.IsTrue(cs.AddedEntities.Contains(newDetail1));  // the entity added directly
            Assert.IsTrue(cs.AddedEntities.Contains(newProduct1)); // inferred via Detail.Product ER
            Assert.IsTrue(cs.AddedEntities.Contains(newCategory)); // inferred via Product.Category ER
            Assert.IsTrue(cs.AddedEntities.Contains(newProduct2)); // inferred via Category.Products EC

            // verify that inferred Adds can be state transitioned via subsequent
            // calls to Attach
            ec.GetEntitySet <Product>().Attach(newProduct2);
            newProduct2.ProductName += "x";
            cs = ec.GetChanges();
            Assert.AreEqual(3, cs.AddedEntities.Count);
            Assert.AreEqual(1, cs.ModifiedEntities.Count);
            Assert.IsFalse(cs.AddedEntities.Contains(newProduct2));
            Assert.IsTrue(cs.ModifiedEntities.Contains(newProduct2));

            // verify that duplicate references aren't added when an
            // inferred entity is attached
            Assert.AreEqual(2, ec.GetEntitySet <Product>().Count);
        }