Melihat:
1. "Entitas" yang disebutkan dalam artikel ini semuanya dihasilkan oleh LINQ TO SQL (yaitu .dbml)
2. Anda perlu memahami bagaimana LINQ TO SQL mengimplementasikan asosiasi tabel, EntitySet dan EntityRef
Mungkin setelah melihat judulnya Anda akan berpikir bahwa pertanyaan tersebut relatif abstrak, jadi izinkan saya memberikan contoh untuk menjelaskan masalahnya secara detail.
Dalam arsitektur N-tier berdasarkan LINQ TO SQL, jika kita perlu memperbarui suatu entitas, prosesnya harus sebagai berikut:
proses
BLL.GetModel(p=>p.id==1) --> Ubah nilai atribut (bidang) yang sesuai --> BLL.Update(Entitas entitas) --> DAL.Update(Entitas entitas) --> Pembaruan berhasil
Saat ini, kita perlu meneruskan entitas ini dari lapisan bisnis (BLL) ke lapisan akses data (DAL). Ketika metode GetModel mengembalikan entitas, DataContext akan segera dirilis, dan kemudian diinstance ulang ketika DAL. Metode pembaruan (entitas entitas) dijalankan. Buat DataContext untuk melakukan operasi pembaruan; dapat dilihat bahwa entitas yang diteruskan diteruskan dari DataContext pertama ke DataContext lain. Saat beroperasi di DataContext yang berbeda di LINQ TO SQL, diperlukan operasi tambahan dilakukan terlebih dahulu, yaitu konteks.Entitas.Lampirkan(entitas,benar); Akhirnya konteks.SubmitChanges();
Mari kita lihat kodenya:
kode
kelas BLL
{
pribadi hanya baca DAL dal = DAL baru();
publik LinqToSqlProvider.User GetModel(Ekspresi<Func<LinqToSqlProvider.User, bool>> ekspresi)
{
dal.GetModel(ekspresi);
}
Pembaruan kekosongan publik (LinqToSqlProvider.Entitas pengguna)
{
dal.Update(entitas);
}
}
kelas DAL
{
publik LinqToSqlProvider.User GetModel(Ekspresi<Func<LinqToSqlProvider.User, bool>> ekspresi)
{
LinqToSqlProvider.Entri pengguna = CriTextBroadcast.LinqToSqlProvider.User() baru;
menggunakan (konteks CriTextBroadcastDBDataContext = DataContext)
{
entri = konteks.Pengguna.SingleOrDefault(ekspresi);
}
entri kembali;
}
Pembaruan kekosongan publik (LinqToSqlProvider.Entitas pengguna)
{
menggunakan (konteks CriTextBroadcastDBDataContext = DataContext)
{
konteks.Pengguna.Lampirkan(entri, benar);
konteks.KirimPerubahan();
}
}
}
Faktanya, ketika kita menggunakan kode di atas untuk beroperasi, pengecualian ini akan terjadi:
Mencoba Melampirkan atau Menambahkan entitas, entitas ini bukan entitas baru, dapat diambil dari DataContext lain...
Setelah mengecek banyak informasi tetapi tidak berhasil, akhirnya saya melihat pertanyaan serupa di postingan luar negeri. Ternyata tabel yang berhubungan dengan entitas ini memiliki beberapa tabel terkait, seperti: Pengguna -> Pesan, Pengguna -> Gambar, dll.
Atribut seperti EntitySet<Message> Message akan dibuat secara otomatis saat membuat kelas entitas. Karena kita tidak membacakan konten terkait ini bersama-sama saat mendapatkan entitas, ObjectDisposeException akan muncul di atribut ini saat melampirkan (Lampirkan). digunakan untuk menanyakan entitas ini telah dirilis.
Larutan:
kode
/// <ringkasan>
/// Entitas tambahan LinqToSql dipisahkan dari DataContext asli
/// </ringkasan>
/// <typeparam nama="TEntity"></typeparam>
/// <param nama="entitas"></param>
public static void Detatch<TEntity>(entitas TEntity)
{
Ketik t = entitas.GetType();
Properti System.Reflection.PropertyInfo[] = t.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
foreach (properti var di properti)
{
string nama = properti.Nama;
if (properti.PropertyType.IsGenericType &&
properti.PropertyType.GetGenericTypeDefinition() == typeof(EntitySet<>))
{
properti.SetValue(entitas, null, null);
}
}
Bidang System.Reflection.FieldInfo[] = t.GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
foreach (bidang var di bidang)
{
string nama = field.Nama;
if (field.FieldType.IsGenericType &&
bidang.FieldType.GetGenericTypeDefinition() == typeof(EntityRef<>))
{
field.SetValue(entitas, null);
}
}
System.Reflection.EventInfo eventPropertyChanged = t.GetEvent("PropertyChanged");
System.Reflection.EventInfo eventPropertyChanging = t.GetEvent("PropertyChanging");
jika (eventPropertyChanged != null)
{
eventPropertyChanged.RemoveEventHandler(entitas, null);
}
jika (eventPropertyChanging != null)
{
eventPropertyChanging.RemoveEventHandler(entitas, null);
}
}
Setelah mendapatkan entitas, Anda harus menggunakan metode Detach(entity) untuk memisahkan entitas dari DataContext asli, lalu melampirkannya ke DataContext baru.