Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Batasan multiplisitas melanggar SQL Server 2008 - CodeFirst

Anda mungkin menjadi korban dari konvensi pemetaan EF Code-First yang secara otomatis membuat hubungan antara NationAllies dan toNation Anda tidak ingin memilikinya.

Jika saya memahami Anda dengan benar (tetapi saya tidak 100 persen yakin, jika saya memahaminya), Anda sebenarnya ingin memiliki dua hubungan dan Anda hanya mengekspos satu ujung hubungan di setiap entitas. Jadi, NationAllies TIDAK menunjuk ke toNation tetapi untuk negara Pemilik "tak terlihat" di NationAlly . Anda entitas.

Jika demikian, Anda perlu secara eksplisit menimpa pemetaan konvensi. Di API Lancar EF 4.1 ini bisa terlihat seperti:

public class MyContext : DbContext
{
    public DbSet<Nation> Nations { get; set; }
    public DbSet<NationAlly> NationAllies { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Nation>()
            .HasMany(n => n.NationAllies)
            .WithRequired()
            .Map(conf => conf.MapKey("OwnerID"))
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<NationAlly>()
            .HasRequired(a => a.toNation)
            .WithMany()
            .Map(conf => conf.MapKey("NationID"))
            .WillCascadeOnDelete(false);
    }
}

Pemetaan ini akan membuat dua kunci asing OwnerID dan NationID di NationAllies tabel, keduanya menunjuk ke kunci utama ID di Nations tabel.

Sunting

Berikut adalah aplikasi yang telah saya uji dengan:

  • Buat Aplikasi Konsol baru di VS2010 / .NET 4.0, beri nama "NationsApp"
  • Tambahkan referensi ke "EntityFramework.dll"
  • Hapus konten "Program.cs" dan tempelkan yang berikut ini di:

Isi Program.cs:

using System;
using System.Collections.Generic;
using System.Data.Entity;

namespace NationsApp
{
    public class Nation
    {
        public int ID { get; set; }
        public int name { get; set; }
        public List<NationAlly> NationAllies { get; set; }
    }

    public class NationAlly
    {
        public int ID { get; set; }
        public int level { get; set; }
        public Nation toNation { get; set; }
    }

    public class NationsContext : DbContext
    {
        public DbSet<Nation> Nations { get; set; }
        public DbSet<NationAlly> NationAllies { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Nation>()
                .HasMany(n => n.NationAllies)
                .WithRequired()
                .Map(conf => conf.MapKey("OwnerID"))
                .WillCascadeOnDelete(false);

            modelBuilder.Entity<NationAlly>()
                .HasRequired(a => a.toNation)
                .WithMany()
                .Map(conf => conf.MapKey("NationID"))
                .WillCascadeOnDelete(false);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            using (var context = new NationsContext())
            {
                try
                {
                    // We have three Nations and two Allies
                    Nation nation1 = new Nation() {
                        NationAllies = new List<NationAlly>() };
                    Nation nation2 = new Nation() {
                        NationAllies = new List<NationAlly>() };
                    Nation nation3 = new Nation() {
                        NationAllies = new List<NationAlly>() };
                    NationAlly ally1 = new NationAlly();
                    NationAlly ally2 = new NationAlly();

                    // Nation1 has two Allies
                    // (Nation1 is the "owner" of both Allies)
                    nation1.NationAllies.Add(ally1);
                    nation1.NationAllies.Add(ally2);

                    // toNation of ally1 refers to Nation2
                    ally1.toNation = nation2;
                    // toNation of ally2 refers to Nation3
                    ally2.toNation = nation3;

                    context.Nations.Add(nation1);
                    context.Nations.Add(nation2);
                    context.Nations.Add(nation3);

                    context.SaveChanges();
                }
                catch (Exception e)
                {
                    throw;
                }
            }
        }
    }
}

Anda dapat menyetel breakpoint pada "throw" untuk melihat kemungkinan pengecualian dalam e di debugger.

Ini membuat database bernama NationsApp.NationsContext jika Anda menggunakan SQL Server Express dan tidak memiliki string koneksi lebih lanjut yang ditentukan.

Ini memberikan dua hubungan Nation_NationAllies (FK adalah "OwnerID") dan NationAlly_toNation (FK adalah "NationID"). Semua kolom tidak dapat dibatalkan. Hasil di DB adalah sebagai berikut:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. UPDATE record dalam satu database dengan nilai dari yang lain di SQL Server 2008?

  2. Bagaimana kita bisa melihat tubuh prosedur tersimpan terenkripsi di SSMS?

  3. Menerapkan Beban Tambahan menggunakan Ubah Pengambilan Data di SQL Server

  4. Fungsi format tanggal SQL Server

  5. Bagaimana Anda menghapus log transaksi SQL Server?