2011-08-24 19 views
13

मेरे पास 2 इकाइयां हैं जो संबंधित हैं, लेकिन विरासत एसक्यूएल स्कीमा में एक ही तालिका के लिए अनिवार्य रूप से 2 कुंजी कॉलम हैं (2-कॉलम कुंजी नहीं: नीचे देखें)। मुझे 'गलत कुंजी' कॉलम पर रिश्ते बनाने की ज़रूरत है। क्या एंटिटी फ्रेमवर्क 4.1 में यह घोषणा करने का कोई तरीका है?इकाई फ्रेमवर्क 4.1 - गैर-कुंजी कॉलम के बीच संबंध

Public Class Client 
    Inherits ModelBase 

    <Key(), Required()> 
    Public Property ClientID As Decimal 

    <Required(), StringLength(50)> 
    Public Property ClientCode As String 

    ........ 


Public Class ClientLocation 
    Inherits ModelBase 

    ........ 

    <Required(), StringLength(50)> 
    Public Property ClientCode As String 

    ........ 

    <ForeignKey("ClientCode")> 
    Public Overridable Property Client As Clients.Client 

और त्रुटि मैं हो रही है: मॉडल पीढ़ी के दौरान

* एक या अधिक सत्यापन त्रुटियों का पता चला गया: System.Data.Edm.EdmAssociationConstraint: सभी गुण के प्रकार एक रेफरेंशियल बाधा की निर्भर भूमिका प्रिंसिपल रोल में संबंधित संपत्ति प्रकारों के समान ही होनी चाहिए। संपत्ति 'ClientCode' इकाई 'ClientLocation' पर के प्रकार नहीं है मैच संपत्ति के प्रकार निर्देशात्मक बाधा 'ClientLocation_Client' में इकाई 'ग्राहक' चालू 'clientid'। *

क्योंकि यह मैं सोचता ' मीटर जब मैं वास्तव में ClientLocation.ClientCode> Client.ClientCode मैप करने के लिए कोशिश कर रहा हूँ ClientLocation.ClientCode> Client.ClientID मैप करना चाहते, ...

किसी भी विचार?

धन्यवाद!

+0

"* ... विरासत एसक्यूएल स्कीमा में एक ही टेबल के लिए अनिवार्य रूप से 2 कुंजी कॉलम हैं ... *": क्या आपका मतलब है कि 'क्लाइंट.क्लिएंटोड' डेटाबेस में एक अद्वितीय इंडेक्स वाला कॉलम है? या फिर "2 कुंजी कॉलम ... लेकिन समग्र कुंजी नहीं हैं" क्या हैं? और आप इस क्लाइंट 'क्लाइंट.क्लिएंटोड' के लिए किसी भी तरह 'ClientLocation.Client' को मैप करना चाहते हैं? – Slauma

+0

तालिका में 2 प्रभावी कुंजी हैं, लेकिन दूसरा एक कुंजी के रूप में पहचाना नहीं गया है, और इसमें कोई अनुक्रमणिका नहीं है। उदाहरण के लिए, क्लाइंट आईडी 4 हो सकती है, और क्लाइंटकोड "फोग्रीक" हो सकता है। दोनों संबंधित या आश्रित नहीं हैं, वे दोनों अद्वितीय होने के साथ ही होते हैं। और हाँ, मुझे क्लाइंट.क्लिंटकोड का उपयोग करके मूल तालिका में वापस मैप करने की आवश्यकता है, भले ही इसे मेरी इकाई में एक कुंजी के रूप में चिह्नित न किया जाए। –

+0

आह, मैं देखता हूं, फिर 'क्लाइंटकोड' एक सामान्य स्तंभ है। विशिष्टता व्यापारिक तर्क से गलती से सुनिश्चित की जाती है। मुझे डर है कि लादीलाव का जवाब अंतिम शब्द है। – Slauma

उत्तर

3

इकाई ढांचे की मांग है कि संबंध मुख्य तालिका और संबंधित कॉलम (विदेशी कुंजी) में निर्भर प्राथमिक तालिका में पूरी प्राथमिक कुंजी के बीच बनाया गया है।

+0

तो आपकी समझ से, संबंधों को "मानचित्र" करने का कोई तरीका नहीं है, वैसे ही हम तालिका और कॉलम नामों को "मानचित्र" कर सकते हैं? –

+0

आपको कनेक्शन में उसी तरह मैप करना होगा जैसा आप डेटाबेस में करेंगे। यदि आपके डेटाबेस में टेबल सही ढंग से सेट नहीं हैं, तो EF इसे ठीक करने में सक्षम नहीं है। –

+1

भले ही यह उत्तर शायद सही है, मैं अभी तक इसे और अधिक आम सहमति के बिना स्वीकार करने के लिए तैयार नहीं हूं। क्या कोई और सत्यापित कर सकता है कि रिलेशनशिप फ़ील्ड को ओवरराइड करने में मदद के लिए डेटा एनोटेशन <टेबल ("पुरानाटेबलनाम")> और <कॉलम ("पुराना कॉलमनाम")> जैसी कोई विधि नहीं है? –

0

(यह केवल Ladislav के जवाब देने के लिए एक परिशिष्ट है, स्वीकार करते हैं और इनाम मेरे जवाब देने के लिए नहीं जाना चाहिए।)

मैं आश्चर्य होगा यदि ऐसी कोई सुविधा कभी एफई में लागू किया जाएगा यदि। क्यूं कर? क्योंकि आप एक रिलेशनल डेटाबेस में ऐसे रिश्ते भी नहीं बना सकते हैं। एक रिलेशनल डीबी (कम से कम SQL सर्वर और शायद सबसे अधिक या अन्य सभी) में एक विदेशी कुंजी संबंध मांगता है कि मुख्य पक्ष एक स्तंभ है जो या तो प्राथमिक कुंजी है या इसकी अनूठी कुंजी बाधा है। जो समझ में आता है क्योंकि एक प्रमुख कुंजी को प्रिंसिपल टेबल में अद्वितीय पंक्ति का संदर्भ देना चाहिए।

अब, ईएफ केवल प्रमुख कुंजी कॉलम के लिए अद्वितीय कुंजी कॉलम के संबंधों का समर्थन भी नहीं करता है। यह ऐसा कुछ है जो संभवतः भविष्य में समर्थित हो सकता है। लेकिन गैर-अद्वितीय और गैर प्राथमिक-कुंजी कॉलम के लिए विदेशी कुंजी संबंधों का समर्थन करना मुझे समझ में नहीं आता है।

यदि आप मुख्य तालिका के लक्ष्य कॉलम में मान अद्वितीय नहीं हैं तो आप क्या होने की उम्मीद करते हैं? क्या आप एक अपवाद चाहते हैं - उदाहरण के लिए - लोड करने की कोशिश करें ClientLocation.Client - "नेविगेशन संपत्ति लोड नहीं कर सकता है 'क्लाइंट' क्योंकि विदेशी कुंजी एक अद्वितीय लक्ष्य" या चेतावनी "का संदर्भ नहीं देती है" क्लाइंट लोड किया गया था लेकिन वहां एक और है, यह सुनिश्चित नहीं कर सकता कि मैंने वह व्यक्ति लोड किया जिसे आप चाहते थे " या ऐसा कुछ?

यदि आप स्वयं को एक पक्ष करना चाहते हैं तो मैं विचार छोड़ दूंगा, नेविगेशन संपत्ति को हटा दूंगा और आपके LINQ प्रश्नों में Join के साथ बहुत कुछ करने के लिए दिशा में सोच सकता हूं।

0

शायद एसोसिएशन विशेषता आपका उत्तर है, एसोसिएशन का उपयोग करके आप निर्दिष्ट कर सकते हैं कि संबंध के प्रत्येक किनारे में कौन सी चाबियाँ उपयोग की जाएंगी।

इस तरह कुछ कोड:

[ForeignKey()] 
[Association("SomeNameForAssociation","TheKeyInThisEntity","TheKeyOnTheAssociationTargetEntity")] 
public virtual Examination Examination { get; set; } 

और अगर मैं अपने प्रश्न को समझते हैं, आप कोड में बदल जानी चाहिए:

Public Class Client 
    Inherits ModelBase 

    <Key(), Required()> 
    Public Property ClientID As Decimal 

    <Required(), StringLength(50)> 
    Public Property ClientCode As String 

    ........ 


Public Class ClientLocation 
    Inherits ModelBase 

    ........ 

    <Required(), StringLength(50)> 
    Public Property ClientCode As String 

    ........ 

    <ForeignKey("ClientCode")> 
    <Association("ClientClientCodes","ClientCode","ClientCode")> 
    Public Overridable Property Client As Clients.Client 

पहले "ClientCode": ClientCode में महत्वपूर्ण स्तंभ का नाम। दूसरा "क्लाइंटकोड": क्लाइंटकोड में प्रमुख कॉलम का नाम जिसे आप उपयोग करना चाहते हैं।

नोट: मैंने अभी तक इस विशेषता का उपयोग नहीं किया है, लेकिन इसके दस्तावेज़ीकरण और इसके नाम और इसके तर्क नामों को सफलतापूर्वक आपकी आवश्यकताओं को पूरा करना चाहिए।

+0

मुझे संदेह है कि '[एसोसिएशन] 'विशेषता का एंटिटी फ्रेमवर्क में कोई प्रभाव पड़ता है। यह LINQ से SQL के लिए केवल एक मैपिंग विशेषता है। – Slauma

2

भले ही यह संभव नहीं है, फिर भी आप LINQ क्वेरी का उपयोग कर दो तालिकाओं में शामिल हो सकते हैं (सी #) (यह question भी देखें)।

var result = from a in ctx.Client 
      join b in ctx.ClientLocation 
      on a.ClientCode equals b.ClientCode 
      select new { Client = a, Location = b }; 

आप केवल नेविगेशन संपत्ति क्लाइंट.क्लिंट लोकेशन और क्लाइंटलोकेशन.क्लिएंट खो रहे हैं। यह इस तरह से करने के लिए थोड़ा और बोझिल है, लेकिन फिर भी यह संभव है।

यदि आप SQL योजना का विस्तार करने के इच्छुक हैं तो आप क्लाइंटलोकेशन क्लाइंट जैसी एक और तालिका जोड़ सकते हैं जो क्लाइंट और क्लाइंटलोकेशन दोनों के लिए विदेशी कुंजी के साथ एम: एन तालिका के रूप में कार्य करता है और दोनों समग्र कुंजी के रूप में कार्य करता है। (सी #) फिर आप इतने तरह नेविगेट कर सकता है

var client = myClientLocation.ClientLocationClients.First().Client; // there's only one 

यह पंक्ति हालांकि जैसे ही आप एक ClientLocation कोई संगत ग्राहक है और निश्चित रूप से आप अपना एक्सटेंशन तालिका सिंक करने के लिए क्लाइंट में एक ट्रिगर निर्धारित करना होगा कि राशि के रूप में असफल हो जायेगी और डिस्प्ले को कैस्केडिंग करने के लिए कॉन्फ़िगर करें और क्लाइंट स्थान को क्लाइंट से पहले डालने की आवश्यकता है, अन्यथा ट्रिगर असफल हो जाएगा ... कुल मिलाकर मैं सिर्फ एक चेतावनी बोलना चाहता हूं कि यह काफी खतरनाक मार्ग हो सकता है।

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