2012-08-16 18 views
14

मैं डेटा मैं उन्हें में है किlinq-2-sql अतिरिक्त अनावश्यक वस्तुओं को क्यों बनाता है?

जनक टेबल

Id Name 
1 John 

बाल टेबल

है तो

CREATE TABLE [Parent](
    [Id] [int] IDENTITY(1,1) NOT NULL, 
    [Name] [nvarchar](256) NOT NULL)  
ALTER TABLE [Parent] ADD CONSTRAINT [PK_Parent_Id] PRIMARY KEY ([Id])  

CREATE TABLE [Child](
    [Id] [int] IDENTITY(1,1) NOT NULL, 
    [ParentId] [int] NOT NULL, 
    [Name] [nvarchar](256) NOT NULL)  
ALTER TABLE [Child] ADD CONSTRAINT [PK_Child_Id] PRIMARY KEY ([Id]) 
ALTER TABLE [Child] ADD CONSTRAINT [FK_Child_Parent_ID] 
    FOREIGN KEY([ParentId]) REFERENCES [Parent] ([Id]) 

की तरह एक डेटाबेस में एक सरल जनक बाल तालिका है

Id ParentId Name 
1  1 Mike 
2  1 Jake 
3  1 Sue 
4  1 Liz 

इन तालिकाओं को Parent और Child सी # ऑब्जेक्ट्स को विजुअल स्टूडियो में लिंक-2-एसक्यूएल डिजाइनर का उपयोग करके बिना किसी मानक विकल्प के मैप किए गए हैं।

मैं अपने माता पिता के साथ सभी बच्चे क्वेरी करने के लिए आप देख सकते हैं एक Parent वस्तु हर Child लिए बनाया गया था

public partial class Parent 
{ 
    static int counter = 0; 
    //default OnCreated created by the linq to sql designer 
    partial void OnCreated() 
    { 
     Console.WriteLine(string.Format("CreatedParent {0} hashcode={1}", 
      ++counter , GetHashCode())); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     using (var db = new SimpleDbDataContext()) 
     { 
      DataLoadOptions opts = new DataLoadOptions(); 
      opts.LoadWith<Child>(c => c.Parent); 
      db.LoadOptions = opts; 
      var allChildren = db.Childs.ToArray(); 
      foreach (var child in allChildren) 
      { 
       Console.WriteLine(string.Format("Parent name={0} hashcode={1}", 
        child.Parent.Name, child.Parent.GetHashCode())); 

      } 
     } 
    } 
} 

उपरोक्त कार्यक्रम के उत्पादन

CreatedParent 1 hashcode=53937671 
CreatedParent 2 hashcode=9874138 
CreatedParent 3 hashcode=2186493 
CreatedParent 4 hashcode=22537358 
Parent name=John hashcode=53937671 
Parent name=John hashcode=53937671 
Parent name=John hashcode=53937671 
Parent name=John hashcode=53937671 

है एक साधारण परीक्षण कार्यक्रम बनाया डेटाबेस में केवल अंततः त्याग दिया जाना है।

सवाल:

  1. क्यों Linq-2-Sql इन अनावश्यक अतिरिक्त Parent वस्तुओं को बनाने करता है?
  2. अतिरिक्त Parent ऑब्जेक्ट्स बनाने से बचने के लिए कोई विकल्प हैं?
+0

यह सिंगलटन ऑब्जेक्ट्स नहीं बनाता है जैसा कि आप उम्मीद कर रहे हैं और न ही इसे चाहिए। क्या होगा यदि आपके पास एक प्रश्न है जो एक ऑब्जेक्ट का चयन करता है और आप एक ही आईडी पर अपडेट क्वेरी लिखना शुरू करते हैं? क्या आपको परिवर्तन सबमिट करने से पहले तुरंत परिवर्तन के परिणाम देखना चाहिए? प्रत्येक क्वेरी के लिए एक अद्वितीय उदाहरण बनाया गया है। –

+0

@ जेफमर्काडो, नहीं: एल 2 एस केवल प्रति टेबल और कुंजी के एक उदाहरण को हाथ से बाहर करता है। यह ओआरएम (पहचान मानचित्र) की एक महत्वपूर्ण विशेषता है। – usr

उत्तर

12

यह LoadWith लागू करने का एक दुष्प्रभाव है।

from c in children 
select { Child = c, Parent = c.Parent } 

आप देख सकते हैं, हम जनक एक बार हर बच्चे के लिए (एक आंतरिक में शामिल होने) लोड कर रहे हैं: LINQ एसक्यूएल के लिए करने के लिए आंतरिक रूप से आपकी क्वेरी बदल देता है। पहचान प्रभाव की वजह से यह प्रभाव आम तौर पर दिखाई नहीं देता है। ओआरएम सुनिश्चित करते हैं कि इकाई ऑब्जेक्ट्स कभी भी (तालिका, प्राथमिक कुंजी) द्वारा डुप्लिकेट नहीं होते हैं। जब आप अपडेट करते हैं तो यह आसान होता है।

LINQ से SQL सर्वर से लौटा परिणाम सेट पढ़ता है (इसमें एक ही अभिभावक एन बार होता है!) और इसे ऑब्जेक्ट्स में पूरा करता है। भौतिककरण के बाद ही, पहचान मानचित्र अपना काम करता है और डुप्लिकेट पेरेंट उदाहरणों को त्याग देता है।

वही प्रभाव एक ही इकाई को कई बार लौटने वाले सभी प्रश्नों के लिए काम करता है।

+3

बिल्कुल यह एक आंतरिक शामिल है। यह इस क्वेरी को लिखने और एसएसएमएस में चलने जैसा है। चुनें * बच्चे से पर child.ParentId = Parent.Id ... माता-पिता शामिल हों जब आप वास्तव में इस क्वेरी आप प्रत्येक बच्चे के लिए कोई नई बात नहीं पैरेंट आईडी मिल चलाने के लिए, यहाँ वी.एस. SQL मानक के मानक नक्शेकदम पीछा कर रहा है। – MStp

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