NHibernate Lancar: Pelanggaran Kunci Asing atau nilai Null

Hai teman-teman, saya mengalami beberapa masalah nyata dengan pemetaan menggunakan nhibernate yang lancar. Saya menyadari ada BANYAK postingan di situs ini dan banyak postingan lainnya yang berfokus pada jenis pemetaan tertentu, tetapi sampai saat ini, saya belum menemukan solusi yang dapat menyelesaikan masalah saya.

Inilah yang saya punya:

namespace MyProject.Models.Entites
{
    public class Project
    {
       public virtual Guid Id {get; set;}
       // A load of other properties
       public virtual ProjectCatagory Catagory{get;set;}           
    }
}

dan kemudian peta:

namespace MyProject.DataAccess.ClassMappings
{
    public class ProjectMap : ClassMap<Project>
    {
        public ProjectMap()
        {
            Id(x => x.Id);
            Map(x => x.Title);
            Map(x => x.Description);
            Map(x => x.LastUpdated);
            Map(x => x.ImageData).CustomSqlType("image");
            HasOne(x => x.Catagory);           
        }
    }
}

Jadi seperti yang Anda lihat, saya punya proyek yang berisi properti kategori. Saya tidak terlalu tertarik pada database relasional tetapi dari apa yang saya dapat bayangkan, ini adalah hubungan banyak-satu di mana banyak Proyek dapat memiliki satu kategori. Tidak, proyek tidak boleh masuk dalam lebih dari satu kategori.

Jadi sekarang kita punya:

namespace MyProject.Models.Entities
{
   public class ProjectCatagory
   {
        public virtual Guid Id { get; set; }
        public virtual String Name { get; set; }
   }
}

dan petanya:

public ProjectCatagoryMap()
{
    Id(x => x.Id);
    Map(x => x.Name);
}

Masalahnya adalah, itu tidak berhasil! Saya akan melakukan sesuatu yang mirip dengan yang berikut ini dalam pengujian unit:

Project myproject = new Project("Project Description");
// set the other properties
myProject.Catagory = new ProjectCatagory(Guid.New(), "Test Catagory");
repository.Save(myProject);

Sekarang saya telah mencoba sejumlah konfigurasi pemetaan dan database ketika mencoba membuatnya berfungsi. Saat ini, tabel database Proyek memiliki kolom, "Catagory_id" (yang tidak saya letakkan di sana, saya berasumsi NH menambahkannya sebagai hasil pemetaan) dan saya ingin itu disetel agar tidak mengizinkan nol. Namun, ketika disetel seperti itu, saya mendapatkan pengecualian yang menjelaskan bahwa saya tidak dapat memasukkan nilai nol ke dalam tabel (walaupun selama debug, saya telah memeriksa semua properti pada objek Proyek dan BUKAN nol).

Atau, saya dapat mengizinkan tabel untuk menerima null ke dalam kolom itu dan itu hanya akan menyimpan objek Proyek dan sepenuhnya mengabaikan properti Kategori saat menyimpan, oleh karena itu, ketika diambil, tes untuk memeriksa apakah kategori yang tepat telah dikaitkan dengan proyek gagal .

Jika saya ingat dengan benar, pada satu titik saya menggunakan ProjectMap:

References(x => x.Catagory).Column("Catagory_id").Cascade.All().Not.Nullable();

ini mengubah pengecualian dari "Tidak dapat memasukkan nilai nol" menjadi pelanggaran kunci asing.

Saya menduga akar dari semua kerumitan ini berasal dari kurangnya pemahaman saya tentang pengaturan basis data relasional karena saya memiliki entitas lain dalam proyek ini yang tidak memiliki ketergantungan eksternal yang berfungsi baik dengan NHibernate, mengesampingkan masalah pengkodean apa pun yang mungkin saya sebabkan ketika membuat repositori.

Bantuan apa pun sangat dihargai. Terima kasih.


person SomeGuy    schedule 14.06.2010    source sumber
comment
Silakan ubah judul menjadi seperti Fluent NHibernate: Masalah dengan HasOne untuk membuatnya lebih spesifik.   -  person Stefan Steinegger    schedule 14.06.2010


Jawaban (3)


Masalah utama di sini adalah kesalahpahaman umum tentang relasi "satu-ke-satu" dalam database relasional dan pemetaan HasOne di Fluent. Istilah-istilah dalam pemetaan adalah istilah-istilah relasional. (Fluent mencoba untuk "mempercantik" mereka sedikit yang membuatnya lebih buruk menurut IMO. HasOne sebenarnya berarti: satu lawan satu.)

Lihatlah Fluent wiki:

HasOne biasanya dicadangkan untuk kasus khusus. Secara umum, Anda akan menggunakan hubungan Referensi di sebagian besar situasi (lihat: menurut saya yang Anda maksud adalah banyak-ke-satu).

Solusinya sangat sederhana, cukup tukar HasOne dengan References (one-to-one hingga many-to-one dalam file pemetaan XML). Anda mendapatkan kunci asing di database yang mereferensikan ProjectCatagory.


Relasi satu-ke-satu yang nyata dalam database relasional idealnya dipetakan dengan sinkronisasi kunci utama. Ketika dua objek berbagi kunci utama yang sama, maka Anda tidak membuang-buang ruang untuk kunci asing tambahan dan dipastikan menjadi kunci satu-ke-satu.

Untuk menyinkronkan kunci utama, Anda perlu menghubungkan kunci yang satu dengan yang lain. Bagaimanapun ini berhasil, bukan itu yang Anda butuhkan di sini.

person Stefan Steinegger    schedule 14.06.2010
comment
Saya menyadari bahwa HasOne() sebenarnya salah dalam istilah ini, tetapi seperti yang dikatakan di bagian bawah posting, saya telah mencoba menggunakan Referensi() saja dan tidak berhasil, mengatakan bahwa pernyataan penyisipan bertentangan dengan batasan kunci asing pada tabel ProjectCatagory. - person SomeGuy; 14.06.2010

Setelah bermain-main dengan semua opsi pemetaan yang tersedia. Saya menemukan jawabannya serupa dengan yang disarankan.

Seperti yang diduga, HasOne() jelas-jelas salah dan References(x => x.Catagory) adalah bagian dari solusi. Namun, saya masih menerima pengecualian pelanggaran kunci asing hingga:

References(x => x.Catagory).Column("Catagory_id").Cascade.SaveUpdate().Not.Nullable().Not.LazyLoad();

Saya pikir saya akan memperbarui utas jika ada orang lain yang menemukan ini dengan masalah serupa seperti hanya menggunakan References() tidak berhasil.

person SomeGuy    schedule 16.06.2010

Tampaknya kelas ProjectCatagory adalah kelas induk dari Kelas Proyek. Jadi tanpa kelas induk bagaimana kelas anak bisa ada.

Anda harus menggunakan -

Referensi(x => x.Catagory).Column("Catagory_id").Foreignkey("Id");

di sini Foreign Key adalah ID tabel ProjectCatagory Anda.

person ankur pancholi    schedule 06.12.2013