无法让 LINQ To DataSet 在我的项目中使用 2 个表

问题描述 投票:0回答:1

我正在为学校做一个项目。该应用程序有多种形式,每种形式都能够使用多种方法运行查询。我陷入了最后一个表单,因为我似乎无法让 LINQ To DataSet 工作。教师表同时包含教师名称和教师 ID 列(教师 ID 是主键)。我的课程表有 coach_id 和 course_id 列(course_id 是主键)。我需要运行一个将教师名称与教师 ID 相匹配的查询,以便我可以使用教师 ID 在列表框中列出课程 ID。该表单有一个 ComboBox,其中包含 3 种运行查询的方法。根据用户的选择,它将使用该方法运行查询。 TableAdapter 和 DataReader 方法工作正常,只是 LINQ To DataSet 无法工作。 sqlConnection 位于模块级别。我对 LINQ 还很陌生,所以我知道我的代码可能还很遥远。我将首先发布我正在处理的表单的代码,然后发布另一个表单的代码,该表单也执行有效的 LINQ To Dataset,但它只查询一个表。

Imports System.Data
Imports System.Data.SqlClient

Public Class CourseForm
    Private CourseTextBox(5) As TextBox                'We only have 6 columns in Course table
    Private Sub CourseForm_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        If sqlConnection.State <> ConnectionState.Open Then
            MessageBox.Show("Database has not been opened!")
            Exit Sub
        End If

        ComboName.Items.Add("Ying Bai")
        ComboName.Items.Add("Davis Bhalla")
        ComboName.Items.Add("Black Anderson")
        ComboName.Items.Add("Steve Johnson")
        ComboName.Items.Add("Jenney King")
        ComboName.Items.Add("Alice Brown")
        ComboName.Items.Add("Debby Angles")
        ComboName.Items.Add("Jeff Henry")
        ComboName.SelectedIndex = 0
        ComboMethod.Items.Add("TableAdapter Method")
        ComboMethod.Items.Add("DataReader Method")
        ComboMethod.Items.Add("LINQ To DataSet Method")
        ComboMethod.SelectedIndex = 0
    End Sub

    Private Sub cmdSelect_Click(sender As Object, e As EventArgs) Handles cmdSelect.Click
        Dim cString1 As String = "SELECT Course.course_id, Course.course FROM Course JOIN Faculty "
        Dim cString2 As String = "ON (Course.faculty_id = Faculty.faculty_id) AND (Faculty.faculty_name = @name)"
        Dim cmdString As String = cString1 & cString2
        Dim CourseTableAdapter As New SqlDataAdapter
        Dim FacultyTableAdapter As New SqlDataAdapter
        Dim paramFacultyName As New SqlParameter
        Dim sqlCommand As New SqlCommand
        Dim sqlDataReader As SqlDataReader
        Dim sqlDataTable As New DataTable
        Dim ds As New DataSet

        sqlCommand.Connection = sqlConnection
        sqlCommand.CommandType = CommandType.Text
        sqlCommand.CommandText = cmdString
        sqlCommand.Parameters.Add("@name", SqlDbType.Char).Value = ComboName.Text

        If ComboMethod.Text = "TableAdapter Method" Then
            CourseTableAdapter.SelectCommand = sqlCommand
            CourseTableAdapter.Fill(sqlDataTable)
            If sqlDataTable.Rows.Count > 0 Then
                Call FillCourseTable(sqlDataTable)
            Else
                MessageBox.Show("No matched course found!")
            End If
            sqlDataTable.Dispose()
            sqlDataTable = Nothing
            CourseTableAdapter.Dispose()
            CourseTableAdapter = Nothing
        ElseIf ComboMethod.Text = "DataReader Method" Then            ' ------------------------------------------ DataReader method is selected
            sqlDataReader = sqlCommand.ExecuteReader
            If sqlDataReader.HasRows = True Then
                Call FillCourseReader(sqlDataReader)
            Else
                MessageBox.Show("No matched course found!")
            End If
            sqlDataReader.Close()
            sqlDataReader = Nothing
        ElseIf ComboMethod.Text = "LINQ To DataSet Method" Then                    ' ------------------------------------------LINQ To DataSet is selected
            CourseTableAdapter.SelectCommand = sqlCommand
            FacultyTableAdapter.SelectCommand = sqlCommand
            FacultyTableAdapter.Fill(ds, "Faculty")
            CourseTableAdapter.Fill(ds, "Course")
            Dim facultyid = From fi In ds.Tables("Faculty").AsEnumerable()
                            Where fi.Field(Of String)("faculty_name").Equals(ComboName.Text) Select fi.Field(Of String)("faculty_id")

            MessageBox.Show(String.Join(", ", facultyid))
            Dim courseid = From ci In ds.Tables("Course").AsEnumerable()
                           Where ci.Field(Of String)("faculty_id").Equals(facultyid) Select ci.Field(Of String)("course_id")
            CourseList.Items.Clear()
            For Each cRow In courseid
                CourseList.Items.Add(courseid)
            Next
        End If

这是我的项目中运行完美的不同形式。 LINQ To DataSet 查询在这里工作正常,但它只查询一张表。

Imports System.Data
Imports System.Data.SqlClient

Public Class FacultyForm
    Private FacultyTextBox(7) As TextBox           'Faculty table has 8 columns
    Private Sub FacultyForm_Load(sender As Object, e As EventArgs) Handles Me.Load
        If sqlConnection.State <> ConnectionState.Open Then
            MessageBox.Show("Database has not been opened!")
            Exit Sub
        End If

        ComboName.Items.Add("Ying Bai")
        ComboName.Items.Add("Davis Bhalla")
        ComboName.Items.Add("Black Anderson")
        ComboName.Items.Add("Steve Johnson")
        ComboName.Items.Add("Jenney King")
        ComboName.Items.Add("Alice Brown")
        ComboName.Items.Add("Debby Angles")
        ComboName.Items.Add("Jeff Henry")
        ComboName.SelectedIndex = 0
        ComboMethod.Items.Add("TableAdapter Method")
        ComboMethod.Items.Add("DataReader Method")
        ComboMethod.Items.Add("LINQ To DataSet Method")
        ComboMethod.SelectedIndex = 0
    End Sub

    Private Sub cmdSelect_Click(sender As Object, e As EventArgs) Handles cmdSelect.Click
        Dim cmdS1 As String = "SELECT faculty_id, faculty_name, office, phone, college, title, email, fimage FROM Faculty "
        Dim cmdS2 As String = "WHERE faculty_name = @facultyName"
        Dim cmdString As String = cmdS1 & cmdS2
        Dim paramFacultyName As New SqlParameter
        Dim FacultyTableAdapter As New SqlDataAdapter
        Dim sqlCommand As New SqlCommand
        Dim sqlDataReader As SqlDataReader
        Dim sqlDataTable As New DataTable
        Dim ds As New DataSet()

        paramFacultyName.ParameterName = "@facultyName"
        paramFacultyName.Value = ComboName.Text
        sqlCommand.Connection = sqlConnection
        sqlCommand.CommandType = CommandType.Text
        sqlCommand.CommandText = cmdString
        sqlCommand.Parameters.Add(paramFacultyName)

        Call ShowFaculty(FacultyTableAdapter, sqlCommand, ds)

        If ComboMethod.Text = "TableAdapter Method" Then
            'FacultyTableAdapter.SelectCommand = sqlCommand         'moved to ShowFaculty()
            FacultyTableAdapter.Fill(sqlDataTable)
            If sqlDataTable.Rows.Count > 0 Then
                Call FillFacultyTable(sqlDataTable)
            Else
                MessageBox.Show("No matched faculty found!")
            End If
            sqlDataTable.Dispose()
            sqlDataTable = Nothing
            FacultyTableAdapter.Dispose()
            FacultyTableAdapter = Nothing
        ElseIf ComboMethod.Text = "DataReader Method" Then  '------------ Data Reader Method
            sqlDataReader = sqlCommand.ExecuteReader

            If sqlDataReader.HasRows = True Then
                Call FillFacultyReader(sqlDataReader)
            Else
                MessageBox.Show("No matched faculty found!")
            End If
            sqlDataReader.Close()
            sqlDataReader = Nothing
        Else        '---------------------- LINQ To DataSet method is selected
            FacultyTableAdapter.SelectCommand = sqlCommand
            FacultyTableAdapter.Fill(ds, "Faculty")
            Dim facultyinfo = From fi In ds.Tables("Faculty").AsEnumerable()
                              Where fi.Field(Of String)("faculty_name").Equals(ComboName.Text) Select fi
            For Each fRow In facultyinfo
                txtID.Text = fRow.Field(Of String)("faculty_id")
                txtName.Text = fRow.Field(Of String)("faculty_name")
                txtTitle.Text = fRow.Field(Of String)("title")
                txtOffice.Text = fRow.Field(Of String)("office")
                txtPhone.Text = fRow.Field(Of String)("phone")
                txtCollege.Text = fRow.Field(Of String)("college")
                txtEmail.Text = fRow.Field(Of String)("email")
            Next
        End If
        sqlCommand.Dispose()
        sqlCommand = Nothing
    End Sub

如果可能的话,我希望课程表格查询的工作方式与教师表格查询类似,只是它查询 2 个表而不是 1 个表。任何帮助将不胜感激。我不断收到的主要错误是我的列名不属于我的表。他们显然是这么做的。我已多次检查这些表,这些列名称对于所有其他方法都适用,包括教师表单上的单表 LINQ To DataSet 查询。如果您对项目表格有任何疑问,请询问我,我将尽我所能回答。抱歉,如果已经在类似的问题中提出过这个问题,恐怕我对 LINQ 不够熟悉,无法翻译不特定于我的项目的答案。预先感谢您。

sql linq visual-studio-2019 linq-to-dataset
1个回答
0
投票

首先,你所做的不好,代码本身需要修改。

我不建议使用 Linq To Dataset,除非您已经有一个数据集可供使用。相反,直接使用 Linq To SQL(或 Linq To EF)从源获取数据是更好的选择,也更容易。不管怎样,既然你想这样用,那就这么做吧。

在您的代码中有 FillCourseTable()、FillCourseReader() 方法,我不知道。其次,当选择“Linq To DataSet Method”时,不清楚您要做什么。在该块中,尽管当前代码有错误,但您在那里使用 Linq 的原因根本没有意义。如果所有数据都已在数据集中,并且您尝试使用 Linq 进行过滤,那么它会更有意义(即:您的Faculty 和 Course 表并不大,因此您可能已在表单加载时将它们加载到数据集中,然后使用来自该数据集,无需再次从 SQL 服务器查询)。

我会尝试从您自己的代码开始引导您(但消除前 2 个 if、elseif 块,因为它们闻起来也不好):

  • 您有一个选择字符串,您将相同的内容填充到数据集中的两个表中。两个表都只有 Course_id 和 Course 列。
  • 在尝试在该数据集上使用 Linq 时,您正在尝试查询不存在的“faculty_name”字段。
  • 在第二次尝试在该数据集上使用 Linq 时,您再次尝试查询“faculty_id”字段,该字段再次不存在。
  • 最后,最后您尝试使用课程 ID 填写 CourseList(假设之前的行有效)。

我希望现在你明白为什么它一开始不起作用,现在让我们尝试至少以一种可行的方式来做:

    Dim FacultyAndCourses As New DataSet()
    Using adp As SqlDataAdapter = New SqlDataAdapter("select * from Faculty where faculty_name=@name", sqlConnection.ConnectionString)
        adp.SelectCommand.Parameters.Add("@name", SqlDbType.VarChar).Value = ComboName.Text
        adp.Fill(FacultyAndCourses, "Faculty")
    End Using
    
    Dim faculty = (From f In FacultyAndCourses.Tables("Faculty").AsEnumerable() Select f).FirstOrDefault()
    
    If Not faculty Is Nothing
    
        Dim facultyId As Integer = faculty("faculty_id")
    
        MessageBox.Show(String.Join(", ", facultyid)) ' Are you expecting multiple faculties with the same name???
        
        Using adp As SqlDataAdapter = New SqlDataAdapter("select * from Course where faculty_id=@id", sqlConnection.ConnectionString)
            adp.SelectCommand.Parameters.Add("@id", SqlDbType.Int).Value = facultyId
            adp.Fill(FacultyAndCourses, "Courses")
        End Using
        
        Dim courses = From c In FacultyAndCourses.Tables("Courses").AsEnumerable() Select c
    
        CourseList.Items.Clear()
        For Each cRow In courses
            CourseList.Items.Add(Cstr(cRow("course_id"))) ' I am not sure what you are trying to add to this list
        Next
    
    Else
     ' Whatever ...
    End If

它仍然没有多大意义,但会起作用。

© www.soinside.com 2019 - 2024. All rights reserved.