sql >> Database >  >> RDS >> Sqlserver

Multipliciteitsbeperking geschonden SQL Server 2008 - CodeFirst

U bent misschien het slachtoffer van de EF Code-First mapping-conventies die automatisch een relatie creëren tussen NationAllies en toNation die je niet wilt hebben.

Als ik je goed begrijp (maar ik ben er niet 100 procent zeker van, als ik dat doe), wil je eigenlijk twee relaties hebben en je hebt slechts één uiteinde van de relatie in elk van de entiteiten blootgelegd. Dus, NationAllies wijst NIET naar toNation maar naar een "onzichtbare" Eigenaarsnatie in uw NationAlly entiteit.

Als dat het geval is, moet u de conventietoewijzingen expliciet overschrijven. In de Fluent API van EF 4.1 zou dit er als volgt uit kunnen zien:

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

Deze toewijzing zou de twee externe sleutels OwnerID . creëren en NationID in de NationAllies tabel, beide wijzend naar de primaire sleutel ID in de Nations tafel.

Bewerken

Hier is de applicatie waarmee ik heb getest:

  • Maak een nieuwe console-app in VS2010 / .NET 4.0, noem deze "NationsApp"
  • Voeg een verwijzing toe naar "EntityFramework.dll"
  • Wis de inhoud van "Program.cs" en plak in plaats daarvan het volgende in:

Inhoud van 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;
                }
            }
        }
    }
}

Je kunt een breekpunt instellen op "throw" om mogelijke uitzonderingen in e in de debugger te bekijken.

Dit creëert een database met de naam NationsApp.NationsContext als u SQL Server Express gebruikt en geen verdere verbindingsreeksen hebt gedefinieerd.

Het geeft twee relaties Nation_NationAllies (FK is "OwnerID") en NationAlly_toNation (FK is "NationID"). Alle kolommen zijn niet-nullable. Het resultaat in de DB is het volgende:



  1. De uitvoeringstijd van een Mysql-query berekenen op basis van het aantal records

  2. go-mysql:authenticatie-plug-in wordt niet ondersteund tijdens verbinding van go-app-container naar mysql-container

  3. ADDTIME() Voorbeelden – MySQL

  4. bij het gebruik van de Oracle-databasekoppeling is er een fout ORA-12154 TNS Kon de opgegeven verbindings-ID niet oplossen