sql >> Databasteknik >  >> RDS >> Sqlserver

Multiplikitetsbegränsning överträdde SQL Server 2008 - CodeFirst

Du är kanske ett offer för EF Code-First-mappningskonventionerna som automatiskt skapar en relation mellan NationAllies och toNation du inte vill ha.

Om jag förstår dig rätt (men jag är inte 100 procent säker, om jag gör det) så vill du faktiskt ha två relationer och du har bara exponerat ena änden av relationen i var och en av entiteterna. Så, NationAllies pekar INTE på toNation men till en "osynlig" Ägarnation i din NationAlly enhet.

Om så är fallet måste du explicit skriva över konventionsmappningarna. I Fluent API för EF 4.1 kan detta se ut så här:

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

Denna mappning skulle skapa de två främmande nycklarna OwnerID och NationID i NationAllies tabell, båda pekar på primärnyckeln ID i Nations bord.

Redigera

Här är applikationen jag har testat med:

  • Skapa en ny konsolapp i VS2010 / .NET 4.0, döp den till "NationsApp"
  • Lägg till en referens till "EntityFramework.dll"
  • Rensa innehållet i "Program.cs" och klistra istället in följande i:

Innehåll i 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;
                }
            }
        }
    }
}

Du kan ställa in en brytpunkt på "kast" för att se möjliga undantag i e i felsökaren.

Detta skapar en databas som heter NationsApp.NationsContext om du använder SQL Server Express och inte har några ytterligare anslutningssträngar definierade.

Det ger två relationer Nation_NationAllies (FK är "OwnerID") och NationAlly_toNation (FK är "NationID"). Alla kolumner är ej nullbara. Resultatet i DB är följande:



  1. Finns det något sätt att ta bort en rad från mysql efter en viss tid räknat från infogningstiden

  2. Gruppera frågeresultat efter månad och år i postgresql

  3. live nytt meddelande avisering

  4. Vilka är de optimala varchar-storlekarna för MySQL?