public void AddProduct(Product product)
        {
            using (var context = new AuctionModelContainer())
            {
                context.setLazyFalse();
                if (product.Categories.Count() == 0)
                {
                    throw new ValidationException("The product must have at least one category setted!");
                }

                ICollection<Product> products = this.GetProdctByNameAndDescription(product.Name, product.Description);
                foreach (Category category in product.Categories)
                {
                    foreach (Product p in products)
                    {
                        Product productAux = this.GetProdctById(p.IdProduct);
                        context.Products.Attach(productAux);
                        context.Entry(productAux).Collection(pAux => pAux.Categories).Load();
                        foreach (Category pcateg in productAux.Categories)
                            {
                                if (category.Name.Equals(pcateg.Name))
                                    throw new DuplicateException("The same product already exists - same name, description and category");
                            }
                    }
                }

                foreach (Category categ in product.Categories)
                    context.Categories.Attach(categ);
                context.Products.Add(product);
                context.SaveChanges();

            }
        }
        public ICollection<Category> GetAllCategoryForAProduct(Product product)
        {
            using(var context = new AuctionModelContainer())
            {
                context.Products.Attach(product);
                context.Entry(product).Collection(prod => prod.Categories).Load();

                return product.Categories;
            }
        }
        public ICollection<Product> GetAllProductsOfACategory(Category category)
        {
            using (var context = new AuctionModelContainer())
            {
                context.Categories.Attach(category);
                context.Entry(category).Collection(cat => cat.Products).Load();

                ICollection<Product> products = category.Products;
                return products;
            }
        }
        public void UpdateRole(Role role)
        {
            using (var context = new AuctionModelContainer())
               {
                context.Roles.Attach(role);
                var entry = context.Entry(role);
                entry.Property(r => r.Name).IsModified = true;

                context.SaveChanges();
               }
        }
        public void AddRoleToUser(User user,Role role)
        {
            using(var context = new AuctionModelContainer())
            {
                context.setLazyFalse();

                context.Users.Attach(user);
                context.Roles.Attach(role);
                context.Entry(user).Collection(u => u.Roles).Load();
                user.Roles.Add(role);

                context.SaveChanges();
            }
        }
        public Auction GetAuctionById(int id)
        {
            using (var context = new AuctionModelContainer())
            {
                context.setLazyFalse();
                var auctionVar = (from auction in context.Auctions
                               where auction.IdAuction.Equals(id)
                               select auction).FirstOrDefault();

                if (auctionVar == null)
                    throw new EntityDoesNotExistException("Auction with id "+id+" does not exist");
                context.Auctions.Attach(auctionVar);
                //context.Entry(auctionVar).Collection(pAux => pAux.Categories).Load();
                context.Entry(auctionVar).Reference(pAux => pAux.Product).Load();
                return auctionVar;
            }
        }
        public void DropUser(String email)
        {
            User user = GetUserByEmail(email);
            if (user == null)
                throw new EntityDoesNotExistException("The user with email " + email + " does not exist.");

            using (var context = new AuctionModelContainer())
            {
                context.setLazyFalse();
                context.Users.Attach(user);
                context.Entry(user).Collection(u => u.Roles).Load();

                if (user.Roles.Count > 0)
                    throw new DependencyException("User with email " + email + " has roles asigned so it can't be droped.");

                context.Users.Remove(user);
                context.SaveChanges();
            }
        }
        public void DeleteCategory(int id)
        {
            Category category = this.GetCategoryById(id);
            if (category == null)
            {
                throw new EntityDoesNotExistException("Category does not exists!");
            }

            using (var context = new AuctionModelContainer())
            {

                context.Categories.Attach(category);
                context.Entry(category).Collection(categ => categ.Products).Load();
                if (category.Products.Count() > 0)
                {
                    throw new DependencyException("The category has products. It cannot be deleted!");
                }
                context.Categories.Attach(category);
                context.Categories.Remove(category);
                context.SaveChanges();
            }
        }
 public void UpdateCategoryDescription(Category category, String description)
 {
     category.Description = description;
     using (var context = new AuctionModelContainer())
     {
        context.Categories.Attach(category);
        var entry = context.Entry(category);
        entry.Property(r => r.Description).IsModified = true;
        context.SaveChanges();
     }
 }
        public Auction GetAuctionOfAProduct(Product product)
        {
            using (var context = new AuctionModelContainer())
            {
                var auctionVar = (from auction in context.Auctions
                                  join productSel in context.Products on auction.Product.IdProduct equals product.IdProduct
                                  where productSel.IdProduct == product.IdProduct
                                  select auction).FirstOrDefault();

                if (auctionVar != null)
                {
                    context.Auctions.Attach(auctionVar);
                    context.Entry(auctionVar).Reference(auc => auc.User).Load();
                }

                return auctionVar;
            }
        }
        public User GetUserById(int id)
        {
            using (var context = new AuctionModelContainer())
            {
                context.setLazyFalse();
                var userVar = (from user in context.Users
                               where user.IdUser.Equals(id)
                               select user).FirstOrDefault();

                if (userVar == null)
                    throw new EntityDoesNotExistException("User with "+id+" does not exist");

                context.Users.Attach(userVar);
                context.Entry(userVar).Collection(user => user.Roles).Load();
                context.Entry(userVar).Collection(user => user.Auctions).Load();
                context.Entry(userVar).Collection(user => user.GivedRatings).Load();
                return userVar;
            }
        }
        public void RemoveRoleFromUser(User user,Role role)
        {
            using (var context = new AuctionModelContainer())
            {
                context.setLazyFalse();

                context.Users.Attach(user);
                context.Roles.Attach(role);
                context.Entry(user).Collection(u => u.Roles).Load();
                context.Entry(role).Collection(r => r.Users).Load();

                if (!user.Roles.Contains(role))
                   throw new EntityDoesNotExistException("User with email "+user.Email+" hasn't the role with name "+role.Name+" so it can't be remove.");

                user.Roles.Remove(role);

                context.Entry(user).State = EntityState.Modified;
                context.SaveChanges();
            }
        }
        public void UpdateProductDescription(Product product, String description)
        {
            using (var context = new AuctionModelContainer())
                {
                    ICollection<Product> products = this.GetProdctByNameAndDescription(product.Name, description);
                    foreach (Category category in product.Categories)
                    {
                        foreach (Product p in products)
                        {
                            Product productAux = this.GetProdctById(p.IdProduct);
                            context.Products.Attach(productAux);
                            context.Entry(productAux).Collection(pAux => pAux.Categories).Load();
                            foreach (Category pcateg in productAux.Categories)
                            {
                                if (category.Name.Equals(pcateg.Name))
                                    throw new DuplicateException("The same product already exists - same name, description and category");
                            }
                        }
                    }

                    product.Description = description;
                    context.Products.Attach(product);
                    var entry = context.Entry(product);
                    entry.Property(r => r.Description).IsModified = true;
                    context.SaveChanges();
                }
        }
 public Product GetProdctById(int id)
 {
     using (var context = new AuctionModelContainer())
     {
         context.setLazyFalse();
         var prodVar = (from product in context.Products
                         where product.IdProduct == id
                         select product).FirstOrDefault();
         if (prodVar != null)
         {
             context.Products.Attach(prodVar);
             context.Entry(prodVar).Collection(pAux => pAux.Categories).Load();
             //context.Entry(auctionVar).Collection(pAux => pAux.Categories).Load();
             context.Entry(prodVar).Reference(pAux => pAux.Auction).Load();
             if (prodVar.Auction != null)
             {
                 context.Entry(prodVar.Auction).Collection(p => p.ProductActions).Load();
                 context.Entry(prodVar.Auction).Reference(c => c.Currency).Load();
                 context.Entry(prodVar.Auction).Reference(c => c.User).Load();
             }
         }
         return prodVar;
     }
 }
 public Category GetCategoryById(int id)
 {
     using(var context = new AuctionModelContainer())
     {
         context.setLazyFalse();
         var categVar = (from category in context.Categories where category.IdCategory == id
                         select category).FirstOrDefault();
         if (categVar != null)
         {
             context.Categories.Attach(categVar);
             context.Entry(categVar).Collection(categ => categ.Products).Load();
         }
         return categVar;
     }
 }
        public void UpdateEmail(User user, String newEmail)
        {
            if (!user.Email.Equals(newEmail))
            {
                using (var context = new AuctionModelContainer())
                {
                    context.Users.Attach(user);
                    var entry = context.Entry(user);
                    entry.Property(u => u.Email).IsModified = true;

                    context.SaveChanges();
                }
            }
        }
        public User GetUserByEmail(String email)
        {
            using (var context = new AuctionModelContainer())
            {
                var userVar = (from user in context.Users
                               where user.Email.Equals(email)
                               select user).FirstOrDefault();

                if(userVar != null)
                    context.Entry(userVar).Collection(u => u.Auctions).Load();

                return userVar;
            }
        }
 public void UpdateCategory(Category category, String newName)
 {
     Category auxCateg = this.GetCategoryByName(newName);
         if (category.IdParentCategory != null)
             category.ParentCategory = this.GetCategoryById((int)category.IdParentCategory);
         if (category.ParentCategory != null)
             if (this.exists(category.ParentCategory.IdCategory, newName))
                 throw new DuplicateException("You can not add two categories with the same name (" + newName + ").");
         {
             if (this.verifyNameInRoots(newName))
                 throw new DuplicateException("You can not add two categories with the same name (" + newName + ").");
         }
         category.Name = newName;
         using (var context = new AuctionModelContainer())
         {
             context.Categories.Attach(category);
             var entry = context.Entry(category);
             entry.Property(r => r.Name).IsModified = true;
             context.SaveChanges();
         }
 }
        public void UpdateLastName(User user,String newLastName)
        {
            if (!user.LastName.Equals(newLastName))
            {
                user.LastName = newLastName;

                using (var context = new AuctionModelContainer())
                {
                    context.Users.Attach(user);
                    var entry = context.Entry(user);
                    entry.Property(u => u.LastName).IsModified = true;

                    context.SaveChanges();
                }
            }
        }
        public void UpdateRating(Rating rating)
        {
            using (var context = new AuctionModelContainer())
            {
                context.Ratings.Attach(rating);
                var entry = context.Entry(rating);
                entry.Property(r => r.Grade).IsModified = true;

                try
                {
                    context.SaveChanges();
                }
                catch (DbEntityValidationException exc)
                {
                    String message = "";
                    IEnumerable<DbEntityValidationResult> errors = exc.EntityValidationErrors;
                    foreach (DbEntityValidationResult error in errors)
                        foreach (var validationError in error.ValidationErrors)
                            message = message + " " + validationError.PropertyName + ". " + validationError.ErrorMessage;
                    throw new ValidationException(message);
                }
            }
        }