कोड प्रथम: स्वतंत्र संघ बनाम विदेशी प्रमुख संघ?


102

जब भी मैं किसी नए प्रोजेक्ट पर काम करना शुरू करता हूं, मैं अपने साथ मानसिक बहस करता हूं और मैं अपने पोक्सो डिजाइन कर रहा हूं। मैंने कई ट्यूटोरियल / कोड नमूने देखे हैं जो विदेशी प्रमुख संगठनों के पक्ष में लगते हैं :

विदेशी कुंजी एसोसिएशन

public class Order
{
    public int ID { get; set; }
    public int CustomerID { get; set; } // <-- Customer ID
    ...
}

स्वतंत्र संघों के विपरीत :

स्वतंत्र एसोसिएशन

public class Order
{
    public int ID { get; set; }
    public Customer Customer { get; set; } // <-- Customer object
    ...
}

मैंने अतीत में NHibernate के साथ काम किया है, और स्वतंत्र संघों का उपयोग किया है, जो न केवल अधिक OO महसूस करते हैं, बल्कि (केवल आलसी लोडिंग के साथ) मुझे केवल अपनी आईडी के बजाय पूरे ग्राहक ऑब्जेक्ट तक पहुंच देने का लाभ है। यह मुझे उदाहरण के लिए, एक आदेश उदाहरण को पुनः प्राप्त करने की अनुमति देता है और फिर Order.Customer.FirstNameस्पष्ट रूप से शामिल होने के बिना करता है, जो बेहद सुविधाजनक है।

इसलिए पुनरावृत्ति करने के लिए, मेरे प्रश्न हैं:

  1. क्या स्वतंत्र संघों का उपयोग करने में कोई महत्वपूर्ण नुकसान हैं? तथा...
  2. यदि कोई नहीं है, तो विदेशी प्रमुख संघों का उपयोग करने का क्या कारण होगा?

जवाबों:


106

यदि आप ORM का पूरा लाभ उठाना चाहते हैं तो आप निश्चित रूप से इकाई संदर्भ का उपयोग करेंगे:

public class Order
{
    public int ID { get; set; }
    public Customer Customer { get; set; } // <-- Customer object
    ...
}

एक बार जब आप FKs के साथ डेटाबेस से एक इकाई मॉडल उत्पन्न करते हैं तो यह हमेशा इकाई संदर्भ उत्पन्न करेगा। यदि आप उनका उपयोग नहीं करना चाहते हैं तो आपको EDMX फ़ाइल को मैन्युअल रूप से संशोधित करना होगा और FK का प्रतिनिधित्व करने वाले गुणों को जोड़ना होगा। कम से कम यह एंटिटी फ्रेमवर्क v1 में मामला था जहां केवल स्वतंत्र संघों को अनुमति दी गई थी।

एंटिटी फ्रेमवर्क v4 एक नए प्रकार की एसोसिएशन प्रदान करता है जिसे फॉरेन की एसोसिएशन कहा जाता है। स्वतंत्र और विदेशी कुंजी संघ के बीच सबसे स्पष्ट अंतर ऑर्डर क्लास में है:

public class Order
{
    public int ID { get; set; }
    public int CustomerId { get; set; }  // <-- Customer ID
    public Customer Customer { get; set; } // <-- Customer object
    ...
}

जैसा कि आप देख सकते हैं कि आपके पास एफके संपत्ति और इकाई संदर्भ दोनों हैं। दो प्रकार के संघों के बीच अधिक अंतर हैं:

स्वतंत्र एसोसिएशन

  • इसमें अलग वस्तु के रूप में दर्शाया गया है ObjectStateManager। उसका अपना है EntityState!
  • एसोसिएशन बनाते समय आपको हमेशा एसोसिएशन के दोनों सिरों से हकदार चाहिए
  • इस एसोसिएशन को इकाई के रूप में मैप किया जाता है।

विदेशी कुंजी एसोसिएशन

  • इसमें अलग ऑब्जेक्ट के रूप में प्रतिनिधित्व नहीं किया गया है ObjectStateManager। उसके कारण आपको कुछ विशेष नियमों का पालन करना चाहिए।
  • एसोसिएशन बनाते समय आपको एसोसिएशन के दोनों सिरों की आवश्यकता नहीं होती है। चाइल्ड एंटिटी और पैरेंट यूनिट का पीके होना पर्याप्त है लेकिन पीके का मूल्य अद्वितीय होना चाहिए। इसलिए विदेशी कुंजी एसोसिएशन का उपयोग करते समय आपको संबंधों में उपयोग की जाने वाली नई संस्थाओं को अस्थायी यूनिक आईडी भी प्रदान करनी चाहिए।
  • यह जुड़ाव मैप नहीं किया गया है, बल्कि यह संदर्भ संबंधी बाधाओं को परिभाषित करता है।

यदि आप विदेशी कुंजी संघ का उपयोग करना चाहते हैं, तो आपको इकाई डेटा मॉडल विज़ार्ड में मॉडल में विदेशी कुंजी कॉलम शामिल करना होगा ।

संपादित करें:

मैंने पाया कि इन दोनों प्रकार के संघों के बीच का अंतर बहुत अच्छी तरह से ज्ञात नहीं है इसलिए मैंने इस बारे में अधिक जानकारी और इस बारे में मेरी अपनी राय को कवर करते हुए एक छोटा लेख लिखा


आपके बहुत ही व्यावहारिक जवाब के लिए धन्यवाद, और सही शब्दावली पर सिर के लिए भी, जिसने मुझे इस विषय पर और संसाधनों के दोनों तकनीकों के बारे में बहुत सारे संसाधन खोजने में मदद की।
डैनियल लियुज़ी

1
मैं सिर्फ आपके लेख, लादिस्लाव पर आया हूं। बहुत दिलचस्प पढ़ा, और महान संसाधन आगे इन दोनों दृष्टिकोणों के बीच अंतर को समझने के लिए। चीयर्स।
डैनियल लियुज़ी

1
@ गौसज: जैसा कि मैं जानता हूं कि ईएफ 4 (जहां एफके संघों की शुरुआत हुई थी) के बाद से इस तरह से कोई बदलाव नहीं हुआ है।
लादिस्लाव मृका

1
यह और अन्य उत्तर प्रदर्शन की चिंता को छूते नहीं हैं। हालाँकि, खंड 2.2 फैक्टरों के अनुसार, जो MSDN लेख से व्यू जनरेशन के प्रदर्शन को प्रभावित करते हैं , इंडिपेंडेंट एसोसिएशन का उपयोग करके विदेशी कुंजी संघों पर व्यू जनरेशन की लागत को बढ़ाता है।
विवेके

1
@LadislavMrnka: क्या आप ऊपर बताए गए आर्टिस के लिंक को दोहरा सकते हैं? मैं इसे एक्सेस नहीं कर सकता।
विवेके

34

दोनों का उपयोग करें। और आलसी लोडिंग के लिए अनुमति देने के लिए अपने इकाई संदर्भों को आभासी बनाएं। ऐशे ही:

public class Order
{
  public int ID { get; set; }
  public int CustomerID { get; set; }
  public virtual Customer Customer { get; set; } // <-- Customer object
  ...
}

यह अनावश्यक DB लुकअप पर बचाता है, आलसी लोडिंग की अनुमति देता है, और यदि आप जानते हैं कि आप इसे बनना चाहते हैं, तो आपको आसानी से आईडी देखने / सेट करने की अनुमति देता है। ध्यान दें कि दोनों होने से आपकी तालिका संरचना किसी भी तरह से नहीं बदलती है।


5
माना। जैसा कि लदिस्लाव ने सुझाव दिया था, मैंने वही किया। यह वास्तव में आपको दोनों दुनिया का सर्वश्रेष्ठ देता है; संपूर्ण वस्तु जब आपको इसके सभी गुणों की आवश्यकता होती है, और इसकी आईडी जब आपको केवल पीके की आवश्यकता होती है और बाकी की परवाह नहीं करते हैं।
डैनियल लियुज़ी

9

स्वतंत्र एसोसिएशन अच्छी तरह से काम नहीं करता AddOrUpdateहै जो आमतौर पर Seedविधि में उपयोग किया जाता है । जब संदर्भ एक मौजूदा आइटम है, तो इसे फिर से डाला जाएगा।

// Existing customer.
var customer = new Customer { Id = 1, Name = "edit name" };
db.Set<Customer>().AddOrUpdate(customer);

// New order.
var order = new Order { Id = 1, Customer = customer };
db.Set<Order>().AddOrUpdate(order);

परिणाम मौजूदा ग्राहक फिर से डाला जाएगा और नया (पुनः डाला गया) ग्राहक नए आदेश के साथ जुड़ा होगा।


जब तक हम विदेशी कुंजी संघ का उपयोग नहीं करते हैं और आईडी असाइन नहीं करते हैं।

 // Existing customer.
var customer = new Customer { Id = 1, Name = "edit name" };
db.Set<Customer>().AddOrUpdate(customer);

// New order.
var order = new Order { Id = 1, CustomerId = customer.Id };
db.Set<Order>().AddOrUpdate(order);

हमारे पास अपेक्षित व्यवहार है, मौजूदा ग्राहक नए आदेश के साथ जुड़ा होगा।


2
यह एक अच्छी खोज है। हालाँकि, ग्राहक को ऑर्डर करने के लिए कार्य-आस-पास (और मुझे सही तरीका लगता है) इसे db संदर्भ से इस तरह लोड किया जा रहा है: var order = new Order { Id = 1, Customer = db.Customers.Find(1) }; या आप db संदर्भ से ग्राहक को लोड करने के लिए चयन विधि का उपयोग कर सकते हैं। यह स्वतंत्र संगति के साथ काम करता है।
tala9999

4

मैं अनावश्यक लुकअप से बचने के लिए ऑब्जेक्ट दृष्टिकोण का पक्ष लेता हूं। जब आप पूरी फैक्ट्री बनाने के लिए अपनी फैक्ट्री पद्धति को कॉल करते हैं (नेस्टेड संस्थाओं के लिए सरल कॉलबैक कोड का उपयोग करते हुए) तो प्रॉपर्टी ऑब्जेक्ट्स को आसानी से आबाद किया जा सकता है। स्मृति उपयोग के अलावा मैं कोई नुकसान नहीं देख सकता हूं (लेकिन आप अपनी वस्तुओं को कैश कर सकते हैं?)। तो, आप जो कुछ भी कर रहे हैं वह ढेर के लिए स्टैक को प्रतिस्थापित कर रहा है और लुकअप नहीं करने से प्रदर्शन लाभ प्राप्त कर रहा है। मुझे लगता है कि इसका मतलब बनता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.