sql >> Databáze >  >> RDS >> Sqlserver

Omezení násobnosti porušilo SQL Server 2008 - CodeFirst

Možná jste obětí mapovacích konvencí EF Code-First, které automaticky vytvářejí vztah mezi NationAllies a toNation nechcete mít.

Pokud vám správně rozumím (ale nejsem si 100 procent jistý, pokud ano), chcete mít ve skutečnosti dva vztahy a v každé z entit jste odhalili pouze jeden konec vztahu. Takže NationAllies NEUkazuje na toNation ale na "neviditelný" národ vlastníka ve vašem NationAlly entity.

Pokud je to váš případ, musíte explicitně přepsat mapování konvence. V rozhraní Fluent API EF 4.1 by to mohlo vypadat takto:

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

Toto mapování by vytvořilo dva cizí klíče OwnerID a NationID v NationAllies tabulka, oba ukazují na primární klíč ID v Nations tabulka.

Upravit

Zde je aplikace, se kterou jsem testoval:

  • Vytvořte novou konzolovou aplikaci ve VS2010 / .NET 4.0, pojmenujte ji „NationsApp“
  • Přidejte odkaz na "EntityFramework.dll"
  • Vymažte obsah souboru „Program.cs“ a vložte do něj následující:

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

Můžete nastavit bod přerušení na "throw", abyste sledovali možné výjimky v e v ladicím programu.

Tím se vytvoří databáze s názvem NationsApp.NationsContext pokud používáte SQL Server Express a nemáte definovány žádné další připojovací řetězce.

Poskytuje dva vztahy Nation_NationAllies (FK je "OwnerID") a NationAlly_toNation (FK je "NationID"). Všechny sloupce nemají hodnotu null. Výsledek v DB je následující:



  1. Formátovat čas jako 24hodinový vojenský čas?

  2. Náš nový zpravodaj SQLPerformance.com

  3. Nejste to vy, to jsem já (odstraňování problémů s I/O)

  4. while ($row =mysql_fetch_array($result)) - kolik smyček se provádí?