【问题标题】:Return object through 3 lists and one object通过 3 个列表和 1 个对象返回对象
【发布时间】:2016-11-17 09:07:16
【问题描述】:

我有一个查询,它给了我一个带有类别、问题和答案的测验,您可以在下面的查询中看到。但是,我只想使用一个阅读器,并且我希望它尽可能面向对象,这意味着我希望 Quiz 成为根对象。一切都必须通过测验。

如何返回包含类别列表、另一个问题列表和另一个答案列表的测验?

代码如下:

public Quiz GetQuizWithCategoriesWithQuestionsWithAnswers(int id)
    {
        Quiz quiz = null;
        Category category = null;
        Question question = null;
        Answer answer = null;
        dbConnection.connection.Open();
        using (SqlCommand command = dbConnection.connection.CreateCommand())
        {
            command.CommandText = "SELECT Quiz.name, Category.name AS catName, Category.id as CatId, Category.quizId, Question.[description] as questDesc, Answer.[description] as ansDesc FROM Quiz JOIN Category ON Category.quizId = Quiz.id JOIN Question ON Question.categoryId = Category.id JOIN Answer ON Answer.questionId = Question.id WHERE Quiz.id = @id";
            command.Parameters.Add("@id", SqlDbType.Int).Value = id;
            var reader = command.ExecuteReader();
            while (reader.Read())
            {
                if (quiz == null)
                {
                    quiz = new Quiz();
                    quiz.name = reader.GetString(reader.GetOrdinal("name"));
                    quiz.id = reader.GetInt32(reader.GetOrdinal("quizId"));
                }
                if (category != null)
                {
                    if (category.id != reader.GetInt32(reader.GetOrdinal("CatId")))
                    {
                        category = new Category();
                        category.id = reader.GetInt32(reader.GetOrdinal("CatId"));
                        category.name = reader.GetString(reader.GetOrdinal("catName"));
                        quiz.categories.Add(category);
                    }
                }
                else
                {
                    category = new Category();
                    category.id = reader.GetInt32(reader.GetOrdinal("CatId"));
                    category.name = reader.GetString(reader.GetOrdinal("catName"));
                    quiz.categories.Add(category);
                }
                if (question != null)
                {
                    //You'll need to get the question ID or just use the description here instead for comparison
                    if (question.description != reader.GetString(reader.GetOrdinal("questDesc")))
                    {
                        question = new Question();
                        question.description = reader.GetString(reader.GetOrdinal("questDesc"));
                        category.question.Add(question);
                    }
                }
                else
                {
                    question = new Question();
                    question.description = reader.GetString(reader.GetOrdinal("questDesc"));
                    category.question.Add(question);
                }

                answer = new Answer();
                answer.description = reader.GetString(reader.GetOrdinal("ansDesc"));
                question.Answers.Add(answer);
            }
        }
        dbConnection.connection.Close();
        return quiz;
    }

 public class Quiz
    {
        [DataMember]
        public int id { get; set; }
        [DataMember]
        public string name { get; set; }
        [DataMember]
        public List<Category> categories { get; set; }
        [DataMember]
        public List<Player> players { get; set; }

        public Quiz()
        {
            categories = new List<Category>();
        }
    }

 public class Category
    {
        [DataMember]
        public int id { get; set; }
        [DataMember]
        public string name { get; set; }
        [DataMember]
        public int amount { get; set; }
        [DataMember]
        public List<Quiz> quiz { get; set; }
        [DataMember]
        public List<Question> question { get; set; }

        public Category()
        { 
            question = new List<Question>();
        }
    }

    public class Question
        {

            [DataMember]
            public int id { get; set; }
            [DataMember]
            public string description { get; set; }
            [DataMember]
            public Category category { get; set; }
            [DataMember]
            public bool isAnswered { get; set; }
            [DataMember]
            public List<Answer> Answers { get; set; }

            public Question()
            {
                Answers = new List<Answer>();
            }
        }

    public class Answer
        {
            [DataMember]
            public int id { get; set; }
            [DataMember]
            public string description { get; set; }
            [DataMember]
            public Question question { get; set; }
            [DataMember]
            public bool isCorrect { get; set; }

        }

【问题讨论】:

  • 您必须检测 ID 更改的时刻,然后您知道您的“子对象”是一个新的,您必须将最后一个添加到列表中。
  • 您能否以代码为例进行详细说明?我无法想象你想说什么。
  • 问题是,现在,我有 1 个测验,有 1 个类别,有 1 个问题,有 1 个答案,我需要完整的问题列表和答案的完整列表类别 ID
  • 您的查询应该返回一个单测验,问题是您在每次迭代中都覆盖了这些值。我可能会创建一个存储过程,它将在多个 select 语句中返回结果,然后使用 datareader 的NextResult() 方法来获取结果。

标签: c# sql sql-server ado.net sqldatareader


【解决方案1】:

我认为您的问题在于您丢失了值,因为您每次在 while 循环中都重新声明 Quiz 对象,因此它丢失了所有以前的值(列表)。您需要在 while 循环之外(在另一个查询和它自己的循环中)获取 Quiz 对象的基值,并为每个列表单独查询(以避免连接中的重复)

编辑:

或者只是检查测验对象是否已实例化,以及是否需要为类别和问题创建新对象:

using (SqlCommand command = dbConnection.connection.CreateCommand())
            {
                command.CommandText = "SELECT Quiz.name, QuizCategory.quizId, QuizCategory.categoryId, Category.name AS catName, Question.[description], Answer.[description] FROM Quiz JOIN QuizCategory ON QuizCategory.quizId = Quiz.id JOIN Category ON Category.id = QuizCategory.categoryId JOIN Question ON Question.categoryId = Category.id JOIN Answer ON Answer.questionId = Question.id WHERE Quiz.id = @id";
                command.Parameters.Add("@id", SqlDbType.Int).Value = id;
                var reader = command.ExecuteReader();
                while (reader.Read())
                {
                    if(quiz==null)
                    {
                        quiz = new Quiz();
                        quiz.name = reader.GetString(reader.GetOrdinal("name"));
                        quiz.id = reader.GetInt32(reader.GetOrdinal("quizId"));
                    }

                    if(question!=null)
                    {
                        //You'll need to get the question ID or just use the description here instead for comparison
                        if(question.id!=reader.GetInt32(reader.GetOrdinal("questionId"))
                        {
                            category.question.Add(question);
                            question = new Question();
                            question.description = reader.GetString(reader.GetOrdinal("description"));
                        }
                    }
                    else
                    {
                        question = new Question();
                        question.description = reader.GetString(reader.GetOrdinal("description"));
                    }                        

                    if(category!=null)
                    {
                        if(category.id!=reader.GetInt32(reader.GetOrdinal("categoryId"))
                        {
                            quiz.categories.Add(category);
                            category = new Category();
                            category.id = reader.GetInt32(reader.GetOrdinal("categoryId"));
                            category.name = reader.GetString(reader.GetOrdinal("catName"));
                        }
                    }
                    else
                    {
                        category = new Category();
                        category.id = reader.GetInt32(reader.GetOrdinal("categoryId"));
                        category.name = reader.GetString(reader.GetOrdinal("catName"));
                    }

                    answer = new Answer();
                    answer.description = reader.GetString(reader.GetOrdinal("description"));
                    question.Answers.Add(answer);

                }
            }
            if(question!=null)
            {
                category.question.Add(question);
            }
            if(category!=null)
            {
                quiz.categories.Add(category);
            }

【讨论】:

  • 真的有必要吗?您不能有 1 个大查询来获取所有信息吗?
  • 顺便说一下,查询在管理工作室中按预期工作 100%
  • @Kingkong 是的,它自己的查询是完美的,但问题是对于每一行,您都丢弃了整个对象并创建了一个新的 Quiz 对象,以便针对您需要拆分的代码进行优化它。如果你真的想把它放在同一个 while 循环和查询中,只需在循环外声明 Quiz 对象并将其设置为 null。检查它是否为空,如果为空则创建一个新的 Quiz 对象。
  • 等一下,我编辑了一些东西,我马上给你看
  • 这解决了测验的问题,但我的类别只有1个问题和1个答案,我希望1个问题有一个答案列表
猜你喜欢
  • 2018-05-30
  • 2016-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-01
  • 2014-06-05
  • 1970-01-01
相关资源
最近更新 更多