आप शायद ईएफ कोड-फर्स्ट मैपिंग सम्मेलनों के शिकार हैं जो स्वचालित रूप से NationAllies
के बीच संबंध बनाते हैं और toNation
आप नहीं चाहते हैं।
अगर मैं आपको सही ढंग से समझता हूं (लेकिन मैं 100 प्रतिशत निश्चित नहीं हूं, अगर मैं करता हूं), तो आप वास्तव में दो रिश्ते रखना चाहते हैं और आपने प्रत्येक संस्था में रिश्ते के केवल एक छोर को उजागर किया है। तो, NationAllies
toNation
को इंगित नहीं करता है लेकिन आपके NationAlly
. में एक "अदृश्य" स्वामी राष्ट्र के लिए इकाई।
यदि ऐसा है तो आपको सम्मेलन मैपिंग को स्पष्ट रूप से अधिलेखित करने की आवश्यकता है। EF 4.1 के Fluent API में यह कुछ इस तरह दिख सकता है:
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 में एक नया कंसोल ऐप बनाएं, इसे "NationApp" नाम दें
- "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;
}
}
}
}
}
डीबगर में ई में संभावित अपवाद देखने के लिए आप "फेंक" पर ब्रेकपॉइंट सेट कर सकते हैं।
यह एक डेटाबेस बनाता है जिसे NationsApp.NationsContext
. कहा जाता है यदि आप SQL सर्वर एक्सप्रेस का उपयोग कर रहे हैं और आगे कोई कनेक्शन स्ट्रिंग परिभाषित नहीं है।
यह दो रिश्ते देता है Nation_NationAllies
(FK "OwnerID" है) और NationAlly_toNation
(एफके "नेशनआईडी" है)। सभी कॉलम गैर-शून्य हैं। डीबी में परिणाम निम्नलिखित है: