Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Ограничението за множество е нарушено SQL Server 2008 - CodeFirst

Може би сте жертва на конвенциите за картографиране на EF Code-First, които автоматично създават връзка между NationAllies и toNation не искате да имате.

Ако ви разбирам правилно (но не съм 100 процента сигурен, ако го направя), вие всъщност искате да имате две връзки и сте изложили само един край на връзката във всяка от същностите. И така, NationAllies НЕ сочи към toNation но на „невидима“ нация собственик във вашия NationAlly обект.

Ако случаят е такъв, трябва изрично да презапишете съпоставянията на конвенцията. Във Fluent API на EF 4.1 това може да изглежда така:

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

Това съпоставяне ще създаде двата външни ключа OwnerID и NationID в NationAllies таблица, като и двете сочат към първичния ключ ID в Nations таблица.

Редактиране

Ето приложението, с което тествах:

  • Създайте ново конзолно приложение във VS2010 / .NET 4.0, наименувайте го „NationsApp“
  • Добавете препратка към „EntityFramework.dll“
  • Изчистете съдържанието на „Program.cs“ и вместо това поставете следното в:

Съдържание на 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;
                }
            }
        }
    }
}

Можете да зададете точка на прекъсване на "throw", за да наблюдавате възможните изключения в e в програмата за отстраняване на грешки.

Това създава база данни, наречена NationsApp.NationsContext ако използвате SQL Server Express и нямате дефинирани допълнителни низове за връзка.

Той дава две релации Nation_NationAllies (FK е "OwnerID") и NationAlly_toNation (FK е "NationID"). Всички колони са ненулеви. Резултатът в DB е следният:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да генерирате скриптове за повторно създаване на ограничения за външни ключове в база данни на SQL Server - SQL Server / TSQL Урок, част 73

  2. Как един сървър обработва заявки за уеб услуги от множество клиенти

  3. База данни + удостоверяване на Windows + потребителско име/парола?

  4. Урок за SQL Server – Всичко, от което се нуждаете, за да овладеете Transact-SQL

  5. Защо CTE (Common Table Expressions) в някои случаи забавя заявките в сравнение с временните таблици в SQL Server