2011-08-08 10 views
8

मैंने इस समस्या को हल करने की कोशिश कर कई दिनों बिताए हैं। मेरी समस्या का उदाहरण देने के लिए एक सरल परियोजना बनाते समय, मैंने एक संभावित समाधान पर ठोकर खाई। तो, यह एक डबल सवाल है।इकाई फ्रेमवर्क, कोड प्रथम मॉडलिंग और एक चक्रीय संदर्भ

लेकिन पहले, एक छोटे से पृष्ठभूमि जानकारी:

मैं सिर्फ इकाई की रूपरेखा 4.1 (EF) और कोड पहले उपयोग करते हुए मेरे ASP.NET MVC परियोजना के लिए मॉडल बनाने के लिए शुरू कर दिया।

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 

namespace TestApp.Models 
{ 
    public class Family 
    { 
     public int ID { get; set; } 
     public string Name { get; set; } 

     public virtual ICollection<Father> Fathers { get; set; } 
     public virtual ICollection<Mother> Mothers { get; set; } 
    } 

    public class Mother 
    { 
     public int ID { get; set; } 
     public string Name { get; set; } 
     public int FamilyID { get; set; } 

     public virtual ICollection<Child> Children { get; set; } 
     public virtual Family Family { get; set; } 
    } 

    public class Father 
    { 
     public int ID { get; set; } 
     public string Name { get; set; } 
     public int FamilyID { get; set; } 

     public virtual ICollection<Child> Children { get; set; } 
     public virtual Family Family { get; set; } 
    } 

    public class Child 
    { 
     public int ID { get; set; } 
     public string Name { get; set; } 
     public int MotherID { get; set; } 
     public int FatherID { get; set; } 

     public virtual Mother Mother { get; set; } 
     public virtual Father Father { get; set; } 
    } 
} 

और DbContext:: मैं कुछ इस के समान मॉडल की जरूरत है

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Data.Entity; 

namespace TestApp.Models 
{ 
    public class TestContext : DbContext 
    { 
     public DbSet<Family> Families { get; set; } 
     public DbSet<Mother> Mothers { get; set; } 
     public DbSet<Father> Fathers { get; set; } 
     public DbSet<Child> Children { get; set; } 
    } 
} 

(कृपया लंगड़ा उदाहरण बहाना, कि क्या मेरी शुक्रवार तले मस्तिष्क के साथ आने के लिए सक्षम था।)

एक परिवार में कई मां और कई पिता हो सकते हैं। और एक बच्चे की मां और पिता होते हैं। मैंने अपने काम पर .NET गुरुओं में से एक के साथ जांच की, जो इस बात पर सहमत हुए कि इसमें असाधारण कुछ भी नहीं है। कम से कम जहां तक ​​हम देख सकते हैं।

System.Data.SqlServerCe.SqlCeException: निर्देशात्मक संबंध एक चक्रीय संदर्भ जिसकी अनुमति नहीं है में परिणाम होगा

लेकिन जब मैं कोड चलाने के लिए, मैं इस अपवाद मिलता है। [प्रतिबंध नाम = Mother_Family]

मुझे चक्र दिखाई देता है: Family - Mother - Child - Father - Family। लेकिन अगर मैंने डेटाबेस टेबल स्वयं बनाया (जो मैं नहीं करना चाहता, तो मुझे कोड पहले के बारे में यही पसंद है) यह एक पूरी तरह से वैध डेटा संरचना होगी, जहां तक ​​मैं कह सकता हूं।

तो, मेरा पहला सवाल है: कोड का उपयोग करते समय यह समस्या क्यों है? क्या ईएफ को सही तरीके से संभालने के तरीके को बताने का कोई तरीका है?

फिर, जैसा कि मैंने शुरुआत में लिखा था, मेरी समस्या का उदाहरण देने के लिए एक सरल परियोजना बनाते समय, मैंने आकस्मिक रूप से एक संभावित समाधान पर ठोकर खाई। मेरे मॉडलों को परिभाषित करते समय मैं बस कुछ गुणों को भूल गया। निम्न उदाहरण में स्पष्टता के लिए, बजाय उन्हें हटाने की, मैं बाहर टिप्पणी की है मॉडल मैं भूल गया के कुछ हिस्सों:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 

namespace TestApp.Models 
{ 
    public class Family 
    { 
     public int ID { get; set; } 
     public string Name { get; set; } 

     public virtual ICollection<Father> Fathers { get; set; } 
     public virtual ICollection<Mother> Mothers { get; set; } 
    } 

    public class Mother 
    { 
     public int ID { get; set; } 
     public string Name { get; set; } 
     // public int FamilyID { get; set; } 

     public virtual ICollection<Child> Children { get; set; } 
     public virtual Family Family { get; set; } 
    } 

    public class Father 
    { 
     public int ID { get; set; } 
     public string Name { get; set; } 
     // public int FamilyID { get; set; } 

     public virtual ICollection<Child> Children { get; set; } 
     public virtual Family Family { get; set; } 
    } 

    public class Child 
    { 
     public int ID { get; set; } 
     public string Name { get; set; } 
     // public int MotherID { get; set; } 
     // public int FatherID { get; set; } 

     public virtual Mother Mother { get; set; } 
     public virtual Father Father { get; set; } 
    } 
} 

तो, इन SomethingID संदर्भ गुण को हटाने मेरी समस्या का समाधान करने लगता है। जैसा कि आप नमूना प्रोजेक्ट के नियंत्रक में देख सकते हैं, मैं इस पोस्ट के अंत में लिंक कर रहा हूं, मैं अभी भी किसी भी समस्या के बिना mothers.First().Family.Fathers.First().Children.First().Mother.Family.Name जैसी चीजों को चक्र में करने में सक्षम हूं। लेकिन ईएफ और कोड फर्स्ट मॉडलिंग के बारे में सभी ट्यूटोरियल और उदाहरण मैं देख रहा हूं (उदा। this one by Scott Guthrie) इन गुणों को शामिल करते हैं, इसलिए उन्हें गलत उपयोग करना गलत लगता है।

और इसलिए, मेरा दूसरा प्रश्न है: क्या कोई कमी और समस्याएं हैं जिन्हें मैंने अभी तक नहीं खोजा है?

यहां उदाहरण प्रोजेक्ट डाउनलोड करें: http://blackfin.cannedtuna.org/cyclical-reference-test-app.zip, और TestSolution.sln खोलें। उदाहरण परियोजना में संपत्तियों पर टिप्पणी की जाती है। गुण जोड़ने के लिए TestModels.cs में लाइनों को अनदेखा करें, जिसके परिणामस्वरूप चक्रीय संदर्भ अपवाद होता है।

एनबी: समाधान सी: \ TestApp पर स्थित एक SQL CE डेटाबेस बना रहा है और बीजिंग कर रहा है।एसडीएफ

अद्यतन दिसंबर 2011: मैं कभी नहीं इस समस्या को तकनीकी रूप से हल किया है, लेकिन मैं अपनी नौकरी छोड़ दी और दूसरी नौकरी जहाँ मैं माइक्रोसॉफ्ट प्रौद्योगिकियों का उपयोग करने की जरूरत नहीं पाया। हल मेरी समस्या :)

लिखने के लिए प्रयोग किया जाता है पुरानी जगह पर तकनीकी सहायता के रूप में उस तरह जब समस्याओं को ठीक करने: "एक वैकल्पिक हल या समाधान प्रदान की गई है"।

+0

एसएफ पर मैंने बेहतर प्रश्नों में से एक पढ़ा है। बहुत बढ़िया। खुशी है कि आपको अपना 'कामकाज' मिला है! –

उत्तर

0

यह एक ज्ञात समस्या है और आप इसमें शामिल होने वाले पहले व्यक्ति नहीं हैं। जो मैंने सुना है, वे डब्लूसीएफ के आने वाले संस्करण में बेहतर समाधान पर काम कर रहे हैं, हालांकि मेरे अनुभव से समय के लिए आप डेटाकंट्रैक्ट्स बनाने से काफी बेहतर हैं जो तार पर भेजे जाने वाले डेटा का प्रतिनिधित्व करते हैं जिससे डेटा संरचना बदलती है चक्रीय संदर्भ को हटाने के लिए।

मुझे पता है कि यह दर्द है, लेकिन इसमें अन्य लाभ होने की संभावना है कि आप संभवतः उन संरचनाओं में अन्य परिवर्तन करना चाहते हैं, जो आपके क्लाइंट्स को ऑब्जेक्ट्स के साथ खेलने के बजाए वैसे भी उपभोग करते हैं क्योंकि वे आपके डीबी में मौजूद हैं

+0

लेकिन धारावाहिकरण के लिए डेटा का वर्णन करने के लिए डेटाकंट्रैक्ट्स का उपयोग नहीं किया जाता है? मैं अभी तक serialization पर भी नहीं हूँ। – decibyte

3

लेकिन मैं डेटाबेस तालिकाओं अपने आप को बनाया है (जो मैं पसंद नहीं करने के लिए, है कि मैं क्या कोड पहले के बारे में की तरह) यह जहाँ तक मैं बता सकता है एक पूरी तरह से वैध डेटा संरचना होगा,।

यह कुछ है जो आपको दोबारा जांचना चाहिए। अपवाद डेटाबेस से सीधे आता है, न कि इकाई फ्रेमवर्क से। यह संभावना है कि हाथ से बनाए गए समान बाधाओं के साथ एक टेबल संरचना भी अमान्य होगी। ध्यान रखें कि आपकी विदेशी कुंजी गुण Mother.FamilyID, Father.FamilyID, Child.MotherID और Child.FatherID0 शून्य38 नहीं हैं, इसलिए वे आवश्यक संबंधों का प्रतिनिधित्व करते हैं और डेटाबेस में संबंधित कॉलम भी शून्य नहीं होते हैं।

जब आप अपने मॉडल वर्गों से इन सभी गुणों को दूर अपने रिश्तों अचानक वैकल्पिक बन जाते हैं क्योंकि नेविगेशन गुण null हो सकता है। यह अब एक और मॉडल है क्योंकि डीबी में एफके कॉलम शून्य हो सकते हैं! जाहिर है यह एक अनुमत मॉडल है।

आप अपने मॉडल में अब भी विदेशी कुंजी गुण जो आवश्यक संबंध आप नल प्रकार का उपयोग कर सकते हैं के बजाय वैकल्पिक प्रतिनिधित्व करना चाहते हैं: public int? FamilyID { get; set; }, public int? MotherID { get; set; }, आदि

0

मैं ज्यादा एक ही समस्या थी लेकिन मैं इसे का उपयोग कर हल इस उत्तर में सलाह Entity Framework Code First - two Foreign Keys from same table जो वैकल्पिक कॉलम के प्रकार को वैकल्पिक रूप से बदलने से बेहतर काम करती है।

संबंधित मुद्दे