Tôi đã thấy câu hỏi này rất nhiều và trong một số diễn đàn. Tôi đã đi vào nó và đây là một câu trả lời hoàn chỉnh cho những người đã nhìn vào nó.
LinQ không được tạo cho Access. Tuy nhiên, nhiều truy vấn sẽ làm việc với Access, bao gồm cả thủ tục xóa. Vì vậy, theo tôi, chỉ có 2 thiếu sót quan trọng khi làm việc với Access, là:
- không thể lưu dữ liệu.
- không thể kéo và thả các đối tượng vào dbml
Insert sẽ thất bại với lỗi "thiếu dấu chấm phẩy (;)". Điều này là do quy trình lưu LINQ đã được thực hiện để lưu dữ liệu và truy xuất ID khóa chính của bản ghi được lưu trong một lần. Chúng tôi biết rằng bạn không thể thực hiện nhiều câu lệnh SQL trong Access, vì vậy đó là lý do cho sự thất bại đó.
Cập nhật sẽ không thành công với lỗi "không tìm thấy bản ghi".Một thủ tục cập nhật sẽ là nguyên nhân tìm kiếm bản ghi được cập nhật rồi cập nhật nó. Tôi không thể nói tại sao nó sẽ không tìm thấy nó, khi bình thường LinQ truy vấn để tìm một hồ sơ hoạt động tốt.
Vì có rất nhiều lợi ích khi sử dụng LINQ, tôi đã tìm ra cách giải quyết sự thiếu hụt, đồng thời tận hưởng những lợi ích khác trong suốt quá trình đăng ký của tôi. Đây là cách (NB: Mã của tôi nằm trong VB.net, nhưng bạn có thể chuyển đổi nếu cần):
Tạo lớp LINQ to SQL (.dbml) để quản lý LINQ của bạn dựa vào cơ sở dữ liệu truy cập và cách quản lý thủ tục lưu của bạn. Dưới đây là các thủ tục đầy đủ về những gì tôi đã tạo và bây giờ tôi làm việc với LINQ để truy cập mà không có bất kỳ vấn đề nào:
Thêm một DataGridView
vào biểu mẫu. Thêm nút cho Add, Edit & Xóa
Mã để điền vào lưới:
Private Sub ResetForm()
Try
Using db As New AccessDataClassesDataContext(ACCCon)
Dim rows = (From row In db.AccountTypes
Where row.AccountTypeID > 1
Order By row.AccountTypeID Ascending
Select row).ToList()
Me.DataGridView1.DataSource = rows
End Using
Catch ex As Exception
MessageBox.Show("Error: " & vbCr & ex.ToString, "Data Error", MessageBoxButtons.OK)
End Try
End Sub
DetailForm
Mã để thiết lập contro l giá trị
Private Sub ResetForm()
Try
If _accountTypeID = 0 Then
Exit Sub
End If
Using db As New AccessDataClassesDataContext(ACCCon)
'Dim rows = (From row In db.AccountTypes
' Where row.AccountTypeID = _accountTypeID
' Order By row.AccountTypeID Ascending
' Select row.AccountTypeID, row.AccountType, row.LastUpdated).ToList()
Dim rows = (From row In db.AccountTypes
Where row.AccountTypeID = _accountTypeID
Select row).ToList()
For Each s In rows
Me.AccountTypeIDTextBox.Text = s.AccountTypeID
Me.myGuidTextBox.Text = s.myGuid
Me.AccountTypeTextBox.Text = s.AccountType
Me.AcHeadIDTextBox.Text = s.AcHeadID
Me.DescriptionTextBox.Text = s.Description
Me.LastUpdatedDateTimePicker.Value = s.LastUpdated
Next
End Using
Catch ex As Exception
End Try
End Sub
LinQToSQLClass
Bạn sẽ có thêm các đối tượng dữ liệu vào dbml bằng tay kể từ khi bạn không có thể kéo và thả khi sử dụng Access. Cũng lưu ý rằng bạn sẽ phải thiết lập tất cả các thuộc tính của các trường một cách chính xác trong các cửa sổ thuộc tính. Một số thuộc tính không được đặt khi bạn thêm các trường.
Mã để Lưu
Công Chức năng SaveAccountType (Không bắt buộc ByVal loại As String = "Close") As Boolean
Dim success As Boolean = False
Dim row As New AccountType
Using db As New AccessDataClassesDataContext(ACCCon)
If _accountTypeID > 0 Then
row = (From r In db.AccountTypes
Where r.AccountTypeID = _accountTypeID).ToList()(0)
If String.IsNullOrEmpty(row.AccountTypeID) Then
MessageBox.Show("Requested record not found", "Update Customer Error")
Return success
End If
End If
Try
With row
.myGuid = Me.myGuidTextBox.Text
.AccountType = Me.AccountTypeTextBox.Text
.Description = Me.DescriptionTextBox.Text
.AcHeadID = Me.AcHeadIDTextBox.Text
.LastUpdated = Date.Parse(Date.Now())
End With
If _accountTypeID = 0 Then db.AccountTypes.InsertOnSubmit(row)
db.SubmitChanges()
success = True
Catch ex As Exception
MessageBox.Show("Error saving to Customer: " & vbCr & ex.ToString, "Save Data Error")
End Try
End Using
Return success
End Function
Bây giờ thay thế hai dòng sau:
If _accountTypeID = 0 Then db.AccountTypes.InsertOnSubmit(row)
db.SubmitChanges()
với một cái gì đó như thế này:
Dim cmd As IDbCommand
cmd = Me.Connection.CreateCommand()
cmd.Transaction = Me.Transaction
cmd.CommandText = query
If myGuid.Trim.Length < 36 Then myGuid = UCase(System.Guid.NewGuid.ToString())
cmd.Parameters.Add(New OleDbParameter("myGuid", row.myGuid))
cmd.Parameters.Add(New OleDbParameter("AccountType", row.AccountType))
cmd.Parameters.Add(New OleDbParameter("Description", row.Description))
cmd.Parameters.Add(New OleDbParameter("AcHeadID", row.AcHeadID))
cmd.Parameters.Add(New OleDbParameter("LastUpdated", Date.Now))
If AccountTypeID > 0 Then cmd.Parameters.Add(New OleDbParameter("AccountTypeID", row.AccountTypeID))
If Connection.State = ConnectionState.Closed Then Connection.Open()
result = cmd.ExecuteNonQuery()
cmd = Me.Connection.CreateCommand()
cmd.Transaction = Me.Transaction
cmd.CommandText = "SELECT @@IDENTITY"
result = Convert.ToInt32(cmd.ExecuteScalar())
Phần cuối cùng của mã trên là những gì được bạn ID của hồ sơ lưu. Cá nhân, tôi thường làm cho nó một lựa chọn, bởi vì tôi không cần nó trong hầu hết các trường hợp, vì vậy tôi không cần phải thêm chi phí đó để lấy lại dữ liệu mỗi lần lưu một bản ghi, tôi rất vui khi biết bản ghi đã được lưu.
Đó là phí được thêm vào LINQ, điều này làm cho Chèn không thành công với Access. Có thực sự cần thiết để có nó? Tôi không nghĩ vậy.
Bạn có thể đã lưu ý rằng tôi thường đặt các quy trình Cập nhật và Chèn cùng nhau, để tiết kiệm thời gian cho tôi và đã giải quyết cả hai thủ tục Cập nhật Insert & trong một lần.
Mã cho Delete:
Private Sub DelButton_Click(sender As Object, e As EventArgs) Handles DelButton.Click
Using db As New AccessDataClassesDataContext(ACCCon)
Dim AccountTypeID As Integer = Me.DataGridView1.CurrentRow.Cells(0).Value
Dim row = From r In db.AccountTypes Where r.AccountTypeID = AccountTypeID
For Each detail In row
db.AccountTypes.DeleteOnSubmit(detail)
Next
Try
db.SubmitChanges()
Catch ex As Exception
' Provide for exceptions.
MsgBox(ex)
End Try
End Using
End Sub
Bây giờ bạn có thể thưởng thức LINQ để truy cập! Vui lòng mã hóa :)
bạn có thực sự tìm một nhà cung cấp để làm việc với ACCESS không? –
Không, tôi đã quyết định làm điều đó một cách nhàm chán mà không cần LINQ to SQL. –