he visto esta pregunta mucho y en varios foros. Intenté y aquí hay una respuesta completa para aquellos que lo han estado buscando.
LinQ no está hecho para el acceso. Sin embargo, muchas de las consultas funcionarán con Access, incluido el procedimiento de eliminación. Por lo tanto, en mi opinión, sólo hay 2 deficiencias cruciales cuando se trabaja con Access, que son:
- no ser capaz de guardar los datos.
- no ser capaz de arrastrar y soltar objetos sobre la dbml
Insertar fallará con el error "falta punto y coma (;)". Esto se debe a que el procedimiento de guardado de LinQ se realizó para guardar datos y recuperar el ID de clave principal del registro guardado de una vez. Sabemos que no puede ejecutar múltiples sentencias de SQL en Access, por lo que esa es la razón de esa falla.
La actualización fallará con el error "registro no encontrado".Un procedimiento de actualización hará que el registro se actualice y luego se actualice. No puedo decir por qué no lo encontraría, cuando la consulta normal de LinQ para encontrar un registro funciona bien.
Porque hay tanto beneficio en usar LinQ, descubrí cómo evitar la deficiencia, mientras disfruto de los otros beneficios a lo largo de mi aplicación. Esta es la forma (NB: Mis códigos están en VB.net, pero se puede convertir, si es necesario):
Crear el LINQ to SQL (.dbml) de clase para manejar su LinQ contra la base de datos de acceso, y una manera de gerente su procedimiento de guardado Debajo están los procedimientos completos de lo que creé y ahora trabajo con LinQ para acceder sin ningún problema:
Agregue DataGridView
en un formulario. Agrega botones para Añadir, Editar Borrar &

código para rellenar la cuadrícula:
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

Código para establecer contro l, los valores
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
Usted tendrá que añadir los objetos de datos a la dbml manualmente ya que no puede arrastrar y soltar cuando se utiliza acceso. También tenga en cuenta que deberá establecer correctamente todas las propiedades de los campos en la ventana de propiedades. Varias propiedades no se establecen cuando agrega los campos.

código para guardar
Función SaveAccountType Pública (tipo opcional ByVal como secuencia = "Cerrar") 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
Ahora reemplazar estas dos líneas:
If _accountTypeID = 0 Then db.AccountTypes.InsertOnSubmit(row)
db.SubmitChanges()
con algo como esto:
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())
La última parte del código anterior es lo que se obtiene el ID del registro guardado. Personalmente, generalmente lo hago una opción, porque no lo necesito en la mayoría de los casos, así que no necesito agregar esa sobrecarga de recuperar datos cada vez que se guarda un registro, estoy feliz de saber que registro fue guardado
Esa es la sobrecarga agregada a LinQ, que hace que la inserción falle con acceso. ¿Es realmente necesario tenerlo? No lo creo.
Es posible que haya notado que normalmente pongo mis procedimientos de actualización e inserción juntos, de modo que eso me ahorra tiempo y ha solucionado los procedimientos de actualización Insert & de una vez.
Código para Eliminar:
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
Ahora puede disfrutar de LINQ to Accede! Happy coding :)
¿Encontraste realmente un proveedor para trabajar con ACCESS? –
No, simplemente decidí hacerlo de forma aburrida sin LINQ to SQL. –