/// <summary>
        /// Add the answer to Database
        /// </summary>
        /// <param name="data">Answer</param>
        public static void AddAnswer(Answer data, int questionID, int userid)
        {
            using (var db = new QaAContext())
            {
                data.Date = DateTime.Now;
                data.UserId = userid;
                data.QuestionId = questionID;
                db.Answers.Add(data);
                db.SaveChanges();

                HttpContext.Current.Cache.UpdateCache("AnsweredQuestions" + userid, data);
                HttpContext.Current.Cache.UpdateCache("AnswersToQuestion"+questionID, data);
                HttpContext.Current.Cache.UpdateCache("AnswersToQuestion" + questionID+"User"+userid, data);

                //Send mails to the subscripted users
                var question = db.Questions.Where(q => q.Id == questionID).SingleOrDefault();
                IUserMailer usermailer = new UserMailer();
                var tagsOfQuestion = question.QuestionHasTags.Select(s => s.TagId).ToList();
                var tos = db.UserProfiles.Where(up => (up.Subscriptions.Any(u => tagsOfQuestion.Any(x => x == u.TagId)) && up.Email!= null && up.IsVerified==true)).ToList();

                foreach (var user in tos)
                {
                    usermailer.NewAnswer(question, user, data).SendAsync();
                }
            }
        }
 /// <summary>
 /// List the answer based on the id of the questions
 /// </summary>
 /// <param name="id">Question ID</param>
 /// <returns></returns>
 public static List<Answer> GetAllAnswerToOneQuestion(int id)
 {
     using (var db = new QaAContext())
     {
         var q = HttpContext.Current.Cache.GetFromCache("AnswersToQuestion"+id, () =>(from ans in db.Answers where ans.QuestionId == id select ans).ToList());
         return q;
     }
 }
 /// <summary>
 /// List all subcribed tag to one user
 /// </summary>
 /// <param name="userid"></param>
 /// <returns></returns>
 public static List<Tag> AllSubcribeTagToOneUser(int userid)
 {
     using (var db = new QaAContext())
     {
         var q = db.UserHasSubscribes.Where(uhs => uhs.UserId == userid).Select(t => t.Tag).ToList();
         return q;
     }
 }
 /// <summary>
 /// List all subcribed user to one tag
 /// </summary>
 /// <param name="tagid"></param>
 /// <returns></returns>
 public static List<UserProfile> AllSubcribeUserToOneTag(int tagid)
 {
     using (var db = new QaAContext())
     {
         var q = db.UserHasSubscribes.Where(uhs => uhs.TagId == tagid).Select(u => u.UserProfile).ToList();
         return q;
     }
 }
 /// <summary>
 /// Get the list of tags, where the tag starts with tagpart
 /// </summary>
 /// <param name="tagpart"></param>
 /// <returns></returns>
 public static List<Tag> GetStartwithTag(string tagpart)
 {
     using (var db = new QaAContext())
     {
         var q = (from t in db.Tags where t.Name.StartsWith(tagpart) select t).ToList();
         return q;
     }
 }
 /// <summary>
 /// List the all tag
 /// </summary>
 /// <returns></returns>
 public static List<Tag> GetAllTag()
 {
     using (var db = new QaAContext())
     {
         var q = HttpContext.Current.Cache.GetFromCache("Tags", () => ( from t in db.Tags select t).ToList());
         return q;
     }
 }
        /// <summary>
        /// Get the tags based on question ID
        /// </summary>
        /// <param name="id">question Id</param>
        /// <returns></returns>
        public static List<Tag> GetAllTagToOneQuestion(int id)
        {
            using (var db=new QaAContext())
            {

                var q = db.QuestionHasTags.Where(t => t.QuestionId == id).Select(t => t.Tag).ToList();
                return q;
            }
        }
 /// <summary>
 /// Add email to the user
 /// </summary>
 /// <param name="up">UserProfile</param>
 public static void AddEmail(UserProfile up)
 {
     using (var db=new QaAContext())
     {
         var user = db.UserProfiles.Where(u => u.UserId == up.UserId).SingleOrDefault();
         user.Email = up.Email;
         user.IsVerified = false;
         db.SaveChanges();
     }
 }
 /// <summary>
 /// Answer edit
 /// </summary>
 /// <param name="data">Answer's data</param>
 public static void EditAnswer(Answer data)
 {
     using (var db = new QaAContext())
     {
         var q = from a in db.Answers where a.Id == data.Id select a;
         var ans = q.SingleOrDefault();
         ans.Content = data.Content;
         db.SaveChanges();
         HttpContext.Current.Cache.UpdateCache("AnswersToQuestion" + data.QuestionId, data);
         HttpContext.Current.Cache.UpdateCache("AnswersToQuestion" + data.QuestionId + "User" + data.UserId, data);
     }
 }
        /// <summary>
        /// Write the user's vote to the question
        /// </summary>
        /// <param name="questionid">question Id</param>
        /// <param name="userid">User Id</param>
        /// <param name="vote">Vote value</param>
        public static void Vote(int questionid, int userid, int vote)
        {
            using (var db=new QaAContext())
            {
                QuestionHasVote add = new QuestionHasVote();
                add.QuestionId=questionid;
                add.UserId=userid;
                add.Rating=vote;
                db.QuestionHasVotes.Add(add);
                db.SaveChanges();
                HttpContext.Current.Cache.UpdateCache("QuestionVote" + questionid, add);

            }
        }
 /// <summary>
 /// Get the true, if user voted to ansert or else false
 /// </summary>
 /// <param name="answerid">Válasz Id</param>
 /// <param name="userid">User Id</param>
 /// <returns></returns>
 public static bool IsVotedForAnswer(int answerid, int userid)
 {
     using (var db = new QaAContext())
     {
         var q = HttpContext.Current.Cache.GetFromCache("AnswerVote" + answerid, () => (from v in db.AnswerHasVotes
                  where v.AnswerId == answerid && v.UserId == userid
                  select v).SingleOrDefault());
         if (q == null)
         {
             return false;
         }
         else
         {
             return true;
         }
     }
 }
 /// <summary>
 /// Get the true, if user voted to question or else false
 /// </summary>
 /// <param name="questionid">Question Id</param>
 /// <param name="userid">User Id</param>
 /// <returns></returns>
 public static bool IsVotedForQuestion(int questionid, int userid)
 {
     using (var db=new QaAContext())
     {
         var q = HttpContext.Current.Cache.GetFromCache("QuestionVote" + questionid, () => (from v in db.QuestionHasVotes
                  where v.QuestionId == questionid && v.UserId == userid
                  select v).SingleOrDefault());
         if (q == null)
         {
             return false;
         }
         else
         {
             return true;
         }
     }
 }
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();
            //This line is helping in CodeFirst Migration
            Database.SetInitializer(new MigrateDatabaseToLatestVersion<QaAContext, QuestionsAndAnswers.Migrations.Configuration>());
            using (var ctx = new QaAContext())
            {
                ctx.Database.Initialize(false);
            }

            if(!WebSecurity.Initialized)
                WebSecurity.InitializeDatabaseConnection("QaAContext", "UserProfile", "UserId", "UserName", true);
        }
            public SimpleMembershipInitializer()
            {
                Database.SetInitializer<QaAContext>(null);

                try
                {
                    using (var context = new QaAContext())
                    {
                        if (!context.Database.Exists())
                        {
                            // Create the SimpleMembership database without Entity Framework migration schema
                            ((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
                        }
                    }
                    if (!WebSecurity.Initialized)
                        WebSecurity.InitializeDatabaseConnection("QaAContext", "UserProfile", "UserId", "UserName", autoCreateTables: true);
                }
                catch (Exception ex)
                {
                    throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex);
                }
            }
        /// <summary>
        /// Write the user's vote to the answer
        /// </summary>
        /// <param name="answerid">answer Id</param>
        /// <param name="userid">User Id</param>
        /// <param name="vote">Vote</param>
        public static void VoteAnswer(int answerid, int userid, int vote)
        {
            using (var db = new QaAContext())
            {
                AnswerHasVote add = new AnswerHasVote();
                add.AnswerId = answerid;
                add.UserId = userid;
                add.Rating = vote;
                db.AnswerHasVotes.Add(add);
                db.SaveChanges();

                HttpContext.Current.Cache.UpdateCache("AnswerVote" + answerid, add);
            }
        }
        public static EmailIdentifier GetEmailDatasByHash(string hash)
        {
            using (var db=new QaAContext())
            {
                var data=db.EmailIdentifiers.Where(ei => ei.Hash == hash).FirstOrDefault();

                return data;
            }
        }
        /// <summary>
        /// Get the reputation of the user (Reputation=Rating of User's Questions + Rating of User's Answers)
        /// </summary>
        /// <param name="userid">User Id</param>
        /// <returns></returns>
        public static int GetUserRating(int userid)
        {
            using (var db=new QaAContext())
            {

                var qrating = db.QuestionHasVotes.Where(qhv => qhv.Question.UserId == userid).Select(s => s.Rating).ToList();
                var arating = db.AnswerHasVotes.Where(ahv => ahv.Answer.UserId == userid).Select(s => s.Rating).ToList();
                return (qrating == null ? 0 : qrating.Sum()) + (arating == null ? 0 : arating.Sum());

            }
        }
        /// <summary>
        /// Get the questions, which pass to user
        /// </summary>
        /// <param name="userid">User ID</param>
        /// <returns></returns>
        public static List<Question> GetQuestionsFitToUser(int userid)
        {
            using (var db = new QaAContext())
            {

                //Query the tags of user's answered question and count and then we tahe 3 most answered tags

                var usertags = db.Tags.Where(d => d.QuestionHasTags.Any(q => q.Question.Answers.Any(a => a.UserId == userid))).Select(d => new
                {
                    Tag = d,
                    Num = d.QuestionHasTags.Count()
                }).OrderByDescending(o => o.Num).Take(3).Select(t => t.Tag);

                //Take the current time minus 7 day, because we want to know which question come in the last week
                var lastday = DateTime.Now.AddDays(-7);

                //Query the questions,which the last week they were and No replies to them and there are such tag, which tag is user's favourite. Finally take the 10 latest tag
                var fitquestions = db.Questions.Where(q => (q.Date > lastday &&  q.Answers.Count() == 0 && q.QuestionHasTags.Any(qht => usertags.Contains(qht.Tag)) )).OrderByDescending(x => x.Date).Take(10).ToList();

                return fitquestions;
            }
        }
        /// <summary>
        /// List the issue in question
        /// </summary>
        /// <param name="questionid">question ID</param>
        /// <returns></returns>
        public static List<Question> GetRelatedQuestions(int questionid)
        {
            using (var db = new QaAContext())
            {

                //List all tag based on question ID
                var tags = HttpContext.Current.Cache.GetFromCache("QuestionTags" + questionid, () => TagManager.GetAllTagToOneQuestion(questionid).Select(x => x.Id).ToList());

                //Take the questions, where the question has got tag (which there is in tags), and take the most recent of 10
                var releateds = HttpContext.Current.Cache.GetFromCache("ReleatedQuestions" + questionid, () => db.Questions.Where(q => q.QuestionHasTags.Any(qht => tags.Contains(qht.TagId)) && q.Id != questionid).OrderByDescending(d => d.Date).Take(10).ToList());
                return releateds;
            }
        }
        /// <summary>
        /// Get the vote's summa based on QuestionID
        /// </summary>
        /// <param name="id">Question Id</param>
        /// <returns></returns>
        public static int GetVote(int id)
        {
            using (var db = new QaAContext())
            {
                //Get the question's vote based on Question ID
                var vote = HttpContext.Current.Cache.GetFromCache("QuestionVote" + id, () => (from q in db.QuestionHasVotes
                                                                                              where q.QuestionId == id
                                                                                              select q.Rating).ToList());
                //If the rating equals ZERO  -> return 0
                if (vote.Count == 0)
                    return 0;
                //if the rating doesn't equal ZERO -> return vote's summa
                return vote.Sum();

            }
        }
 /// <summary>
 /// User subcribes to more tags
 /// </summary>
 /// <param name="tags"></param>
 /// <param name="user"></param>
 public static void SubcribeToMoreTags(List<Tag> tags, int user)
 {
     using (var db = new QaAContext())
     {
         foreach (var item in tags)
         {
             //Check the subcribe
             var q = (from t in db.UserHasSubscribes where (t.TagId == item.Id && t.UserId == user) select t).FirstOrDefault();
             //if it does not exist yet
             if (q == null)
             {
                 var subc = new UserHasSubscribe
                 {
                     TagId = item.Id,
                     UserId = user
                 };
                 db.UserHasSubscribes.Add(subc);
                 db.SaveChanges();
             }
         }
     }
 }
 /// <summary>
 /// Get the x number of the latest questions 
 /// </summary>
 /// <param name="x">Number of the question</param>
 /// <returns></returns>
 public static List<Question> GetXLatestQuestion(int x)
 {
     using (var db = new QaAContext())
     {
         var q = HttpContext.Current.Cache.GetFromCache("LatestQuestions", () => db.Questions.OrderByDescending(v => v.Date).Take(x).ToList());
         return q;
     }
 }
 public static string SentEmailHash(int userid, int questionid)
 {
     using (var db=new QaAContext())
     {
         var hash=MyHelpers.MD5Encode("u" + userid.ToString() + "q" + questionid.ToString());
         db.EmailIdentifiers.Add(new EmailIdentifier { UserId = userid, QuestionId = questionid, Hash = hash });
         db.SaveChanges();
         return hash;
     }
 }
        /// <summary>
        /// Get the answer from the id
        /// </summary>
        /// <param name="id">Answer's id</param>
        /// <returns></returns>
        public static Answer GetAnswer(int id)
        {
            using (var db=new QaAContext())
            {
                var ans = HttpContext.Current.Cache.GetFromCache("GetAnswer"+id, () => db.Answers.Where(a=>a.Id==id).SingleOrDefault());

                return ans;
            }
        }
        /// <summary>
        /// Get the answers'vote
        /// </summary>
        /// <param name="id">Answer Id</param>
        /// <returns></returns>
        public static int GetVote(int id)
        {
            using (var db = new QaAContext())
            {

                var vote = HttpContext.Current.Cache.GetFromCache("AnswerVote"+id, () => (from ans in db.AnswerHasVotes
                                  where ans.AnswerId == id
                                  select ans.Rating).ToList());
                //if there isn't vote
                if (vote.Count == 0)
                    return 0;
                return vote.Sum();

            }
        }
        /// <summary>
        /// List the all user
        /// </summary>
        /// <returns></returns>
        public static List<UserProfile> GetAllUsers()
        {
            using (var db =new QaAContext())
            {
                var q = from u in db.UserProfiles
                        select u;

                return q.ToList();
            }
        }
        /// <summary>
        /// User subcribe to tag
        /// </summary>
        /// <param name="tag"></param>
        /// <param name="user"></param>
        public static void SubcribeToTag(int tag, int user)
        {
            using (var db = new QaAContext())
            {
                //Check the subcribe
                var q = (from t in db.UserHasSubscribes where (t.TagId == tag && t.UserId == user) select t).FirstOrDefault();
                //if it does not exist yet
                if (q == null)
                {
                    var subc = new UserHasSubscribe
                    {
                        TagId = tag,
                        UserId = user
                    };
                    db.UserHasSubscribes.Add(subc);
                    db.SaveChanges();
                }

            }
        }
 /// <summary>
 /// Get the UserProfil based on ID
 /// </summary>
 /// <param name="id">User Id</param>
 /// <returns></returns>
 public static UserProfile GetUserById(int id)
 {
     using (var db=new QaAContext())
     {
         var q = (from u in db.UserProfiles
                  where u.UserId == id
                  select u).SingleOrDefault();
         return q;
     }
 }
        /// <summary>
        /// Get all answer from one questions of the user
        /// </summary>
        /// <param name="questionid">Question ID</param>
        /// <param name="userid">User ID</param>
        /// <returns></returns>
        public static List<Answer> GetAllAnswerToOneQuestionFromOneUser(int questionid, int userid)
        {
            using (var db=new QaAContext())
            {
                var answers = HttpContext.Current.Cache.GetFromCache("AnswersToQuestion" + questionid+"User"+userid, () => (from a in db.Answers
                               where a.QuestionId == questionid && a.UserId == userid
                               select a).ToList());
                return answers;

            }
        }
 /// <summary>
 /// Verify the email of the user
 /// </summary>
 /// <param name="id">UserID</param>
 public static void VerifyEmail(int id)
 {
     using (var db=new QaAContext())
     {
         var user = db.UserProfiles.Where(u => u.UserId == id).SingleOrDefault();
         if (user == null) return;
         user.IsVerified = true;
         db.SaveChanges();
     }
 }