Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Ràng buộc đa tính năng đã vi phạm SQL Server 2008 - CodeFirst

Có lẽ bạn là nạn nhân của quy ước ánh xạ EF Code-First vốn tự động tạo ra mối quan hệ giữa NationAlliestoNation bạn không muốn có.

Nếu tôi hiểu bạn đúng (nhưng tôi không chắc 100 phần trăm, nếu tôi hiểu), thì bạn thực sự muốn có hai mối quan hệ và bạn chỉ để lộ một đầu mối quan hệ trong mỗi thực thể. Vì vậy, NationAllies KHÔNG trỏ đến toNation nhưng với quốc gia Chủ sở hữu "vô hình" trong NationAlly của bạn thực thể.

Nếu trường hợp đó xảy ra, bạn cần ghi đè rõ ràng các ánh xạ quy ước. Trong API Fluent của EF 4.1, điều này có thể giống như sau:

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);
    }
}

Ánh xạ này sẽ tạo ra hai khóa ngoại OwnerIDNationID trong NationAllies bảng, cả hai đều trỏ đến khóa chính ID trong Nations bảng.

Chỉnh sửa

Đây là ứng dụng tôi đã thử nghiệm:

  • Tạo Ứng dụng bảng điều khiển mới trong VS2010 / .NET 4.0, đặt tên là "NationsApp"
  • Thêm tham chiếu vào "EntityFramework.dll"
  • Xóa nội dung của "Program.cs" và thay vào đó dán nội dung sau vào:

Nội dung của 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;
                }
            }
        }
    }
}

Bạn có thể đặt điểm ngắt trên "ném" để xem các ngoại lệ có thể xảy ra ở e trong trình gỡ lỗi.

Điều này tạo ra một cơ sở dữ liệu có tên là NationsApp.NationsContext nếu bạn đang sử dụng SQL Server Express và không có bất kỳ chuỗi kết nối nào được xác định.

Nó cung cấp hai mối quan hệ Nation_NationAllies (FK là "OwnerID") và NationAlly_toNation (FK là "NationID"). Tất cả các cột đều không thể null. Kết quả trong DB như sau:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cập nhật truy vấn bằng Truy vấn con trong Máy chủ Sql

  2. SQL Server 2008 IDENTITY_INSERT lỗi BẬT khi Chèn

  3. Tối ưu hóa truy vấn SQL bằng cách loại bỏ toán tử Sắp xếp trong kế hoạch Thực thi

  4. SQL:chỉ viết hoa chữ cái đầu tiên

  5. Gói SSIS được thực thi trong Tác nhân máy chủ không hoạt động (ngay cả khi báo cáo thành công)