Bagian berikut menjawab beberapa masalah umum yang mungkin Anda temui saat menerapkan LINQ.
Masalah tambahan ditangani dalam Pemecahan Masalah.
Tidak dapat terhubung
Saya tidak dapat tersambung ke database saya.
Pastikan string koneksi Anda benar dan instans SQL Server Anda berjalan. Perhatikan juga bahwa LINQ to SQL mengharuskan protokol Pipa yang Dinamai diaktifkan. Untuk informasi selengkapnya, lihat Pembelajaran menurut Panduan.
Perubahan pada Database Hilang
Saya membuat perubahan pada data dalam database, tetapi ketika saya mereran aplikasi saya, perubahan tidak lagi ada.
Pastikan Anda memanggil SubmitChanges untuk menyimpan hasil ke database.
Koneksi Database: Buka Berapa Lama?
Berapa lama koneksi database saya tetap terbuka?
Koneksi biasanya tetap terbuka hingga Anda menggunakan hasil kueri. Jika Anda ingin meluangkan waktu untuk memproses semua hasil dan tidak berlawanan dengan penembolokan hasil, terapkan ToList ke kueri. Dalam skenario umum di mana setiap objek hanya diproses satu kali, model streaming lebih unggul di DataReader
dan LINQ to SQL.
Detail penggunaan koneksi yang tepat bergantung pada hal berikut:
Status koneksi jika DataContext dibangun dengan objek koneksi.
Pengaturan string koneksi (misalnya, mengaktifkan Beberapa Kumpulan Hasil Aktif (MARS). Untuk informasi selengkapnya, lihat Beberapa Kumpulan Hasil Aktif (MARS).
Memperbarui Tanpa Kueri
Bisakah saya memperbarui data tabel tanpa terlebih dahulu mengkueri database?
Meskipun LINQ to SQL tidak memiliki perintah pembaruan berbasis set, Anda dapat menggunakan salah satu teknik berikut untuk memperbarui tanpa mengkueri terlebih dahulu:
Gunakan ExecuteCommand untuk mengirim kode SQL.
Buat instans baru objek dan inisialisasi semua nilai (bidang) saat ini yang memengaruhi pembaruan. Kemudian lampirkan objek ke DataContext dengan menggunakan Attach dan ubah bidang yang ingin Anda ubah.
Hasil Kueri Tak Terduga
Kueri saya mengembalikan hasil yang tidak terduga. Bagaimana cara memeriksa apa yang terjadi?
LINQ to SQL menyediakan beberapa alat untuk memeriksa kode SQL yang dihasilkannya. Salah satu yang paling penting adalah Log. Untuk informasi selengkapnya, lihat Dukungan Penelusuran Kesalahan.
Hasil Prosedur Tersimpan Tak Terduga
Saya memiliki prosedur tersimpan yang nilai pengembaliannya dihitung oleh 'MAX()'. Saat saya menyeret prosedur tersimpan ke permukaan O/R Designer, nilai yang dikembalikan tidak benar.
LINQ to SQL menyediakan dua cara untuk mengembalikan nilai yang dihasilkan database dengan cara prosedur tersimpan:
Dengan memberi nama hasil output.
Dengan secara eksplisit menentukan parameter output.
Berikut ini adalah contoh output yang salah. Karena LINQ to SQL tidak dapat memetakan hasil, selalu mengembalikan 0:
create procedure proc2
as
begin
select max(i) from t where name like 'hello'
end
Berikut ini adalah contoh output yang benar dengan menggunakan parameter output:
create procedure proc2
@result int OUTPUT
as
select @result = MAX(i) from t where name like 'hello'
go
Berikut ini adalah contoh output yang benar dengan memberi nama hasil output:
create procedure proc2
as
begin
select nax(i) AS MaxResult from t where name like 'hello'
end
Untuk informasi selengkapnya, lihat Menyesuaikan Operasi Dengan Menggunakan Prosedur Tersimpan.
Kesalahan Serialisasi
Ketika saya mencoba membuat serialisasi, saya mendapatkan kesalahan berikut: "Ketik 'System.Data.Linq.ChangeTracker+StandardChangeTracker' ... tidak ditandai sebagai dapat diserialisasikan."
Pembuatan kode di LINQ to SQL mendukung serialisasi DataContractSerializer. Ini tidak mendukung XmlSerializer atau BinaryFormatter. Untuk informasi selengkapnya, lihat Serialisasi.
Beberapa File DBML
Ketika saya memiliki beberapa file DBML yang berbagi beberapa tabel yang sama, saya mendapatkan kesalahan pengompilasi.
Atur properti Namespace Layanan Konteks dan Namespace Layanan Entitas dari Object Relational Designer ke nilai yang berbeda untuk setiap file DBML. Pendekatan ini menghilangkan tabrakan nama/namespace layanan.
Menghindari Pengaturan Eksplisit Nilai Database-Generated di Sisipkan atau Perbarui
Saya memiliki tabel database dengan kolom 'DateCreated' yang defaultnya SQL 'Getdate()'. Ketika saya mencoba menyisipkan rekaman baru dengan menggunakan LINQ to SQL, nilai akan diatur ke 'NULL'. Saya mengharapkannya diatur ke default database.
LINQ to SQL menangani situasi ini secara otomatis untuk identitas (kenaikan otomatis) dan rowguidcol (GUID yang dihasilkan database) dan kolom tanda waktu. Dalam kasus lain, Anda harus mengatur properti IsDbGenerated=true
dan AutoSync=Always/OnInsert/OnUpdate secara manual.
Beberapa DataLoadOptions
Dapatkah saya menentukan opsi beban tambahan tanpa menimpa yang pertama?
Ya. Yang pertama tidak ditimpa, seperti dalam contoh berikut:
Dim dlo As New DataLoadOptions()
dlo.LoadWith(Of Order)(Function(o As Order) o.Customer)
dlo.LoadWith(Of Order)(Function(o As Order) o.OrderDetails)
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<Order>(o => o.Customer);
dlo.LoadWith<Order>(o => o.OrderDetails);
Kesalahan Menggunakan SQL Ringkas 3.5
Saya mendapatkan kesalahan saat menyeret tabel keluar dari database SQL Server Compact 3.5.
Object Relational Designer tidak mendukung SQL Server Compact 3.5, meskipun runtime bahasa umum LINQ to SQL. Dalam situasi ini, Anda harus membuat kelas entitas Anda sendiri dan menambahkan atribut yang sesuai.
Kesalahan dalam Hubungan Pewarisan
Saya menggunakan bentuk warisan kotak alat di Object Relational Designer untuk menghubungkan dua entitas, tetapi saya mendapatkan kesalahan.
Membuat hubungan tidaklah cukup. Anda harus memberikan informasi seperti kolom diskriminator, nilai diskriminator kelas dasar, dan nilai diskriminator kelas turunan.
Model Penyedia
Apakah model penyedia publik tersedia?
Tidak ada model penyedia publik yang tersedia. Saat ini, LINQ to SQL hanya mendukung SQL Server dan SQL Server Compact 3.5.
Serangan SQL-Injection
Bagaimana LINQ to SQL dilindungi dari serangan injeksi SQL?
SQL injeksi telah menjadi risiko signifikan untuk kueri SQL tradisional yang dibentuk dengan menggabungkan input pengguna. LINQ to SQL menghindari injeksi seperti itu dengan menggunakan SqlParameter dalam kueri. Input pengguna diubah menjadi nilai parameter. Pendekatan ini mencegah perintah berbahaya digunakan dari input pelanggan.
Mengubah Bendera Baca-saja dalam File DBML
Bagaimana cara menghilangkan setter dari beberapa properti saat saya membuat model objek dari file DBML?
Ikuti langkah-langkah berikut untuk skenario tingkat lanjut ini:
Di file .dbml, ubah properti dengan mengubah tanda IsReadOnly menjadi
True
.Tambahkan kelas parsial. Buat konstruktor dengan parameter untuk anggota baca-saja.
Tinjau nilai default UpdateCheck (Never) untuk menentukan apakah itu nilai yang benar untuk aplikasi Anda.
Perhatian
Jika Anda menggunakan Object Relational Designer di Visual Studio, perubahan Anda mungkin ditimpa.
APTCA
Apakah System.Data.Linq ditandai untuk digunakan oleh kode tepercaya sebagian?
Ya, rakitan System.Data.Linq.dll adalah salah satu rakitan .NET Framework yang ditandai dengan atribut AllowPartiallyTrustedCallersAttribute. Tanpa penandaan ini, rakitan dalam .NET Framework dimaksudkan untuk digunakan hanya dengan kode yang sepenuhnya tepercaya.
Skenario utama dalam LINQ to SQL untuk mengizinkan penelepon yang sebagian tepercaya adalah mengaktifkan perakitan LINQ ke SQL untuk diakses dari aplikasi Web, di mana konfigurasi kepercayaan adalah Medium.
Memetakan Data dari Beberapa Tabel
Data di entitas saya berasal dari beberapa tabel. Bagaimana cara memetakannya?
Anda dapat membuat tampilan dalam database dan memetakan entitas ke tampilan. LINQ to SQL menghasilkan SQL yang sama untuk tampilan seperti halnya untuk tabel.
Catatan
Penggunaan tampilan dalam skenario ini memiliki keterbatasan. Pendekatan ini bekerja paling aman bila operasi yang dilakukan pada Table<TEntity> didukung oleh tampilan yang mendasarinya. Hanya Anda yang tahu operasi mana yang dimaksudkan. Misalnya, sebagian besar aplikasi bersifat hanya-baca, dan nomor lain yang cukup besar melakukan operasi Create
/Update
/Delete
hanya dengan menggunakan prosedur tersimpan terhadap tampilan.
Pengumpulan Koneksi
Apakah ada konstruksi yang dapat membantu pengumpulan DataContext?
Jangan mencoba menggunakan kembali instans DataContext. Masing-masing DataContext mempertahankan status (termasuk cache identitas) untuk satu sesi edit/kueri tertentu. Untuk mendapatkan instans baru berdasarkan status database saat ini, gunakan DataContext baru.
Anda masih dapat menggunakan ADO.NET pengumpulan koneksi yang mendasar. Untuk informasi selengkapnya, lihat Kumpulan Koneksi SQL Server (ADO.NET).
Konteks Data Kedua Tidak Diperbarui
Saya menggunakan satu instans DataContext untuk menyimpan nilai dalam database. Namun, DataContext kedua pada database yang sama tidak mencerminkan nilai yang diperbarui. Instans DataContext kedua tampaknya mengembalikan nilai cache.
Perilaku ini secara desain. LINQ to SQL terus mengembalikan contoh/nilai yang sama yang Anda lihat di contoh pertama. Saat membuat pembaruan, Anda menggunakan konkurensi optimis. Data asli digunakan untuk memeriksa status database saat ini untuk menegaskan bahwa data tersebut sebenarnya masih tidak berubah. Jika telah berubah, konflik terjadi dan aplikasi Anda harus mengatasinya. Salah satu opsi aplikasi Anda adalah mengatur ulang status asli ke status database saat ini dan mencoba pembaruan lagi. Untuk informasi selengkapnya, lihat Cara: Mengelola Konflik Perubahan.
Anda juga dapat mengatur ObjectTrackingEnabled ke false, yang menonaktifkan penembolokan dan pelacakan perubahan. Anda kemudian dapat mengambil nilai terbaru setiap kali Anda mengkueri.
Tidak Dapat Memanggil SubmitChanges dalam Mode Baca-saja
Ketika saya mencoba memanggil SubmitChanges dalam mode baca-saja, saya mendapatkan kesalahan.
Mode baca-saja mematikan kemampuan konteks untuk melacak perubahan.