2009-08-21 8 views
6

मेरे पास 2 संबंधित लिंक SQL प्रश्नों के लिए हैं। यह देखने के लिए कि मेरा मॉडल कैसा दिखता है, कृपया नीचे दी गई छवि देखें।एक संदर्भ संदर्भ तालिका में लिंक से एसक्यूएल इकाइयों की उत्सुक लोडिंग

प्रश्न 1

मैं कल्पना करने की कोशिश कर रहा हूँ कि कैसे करने के लिए उत्सुक मेरी User वर्ग/मेज पर लोड User.AddedByUser क्षेत्र। यह क्षेत्र User.AddedByUserId फ़ील्ड पर रिश्ते से उत्पन्न होता है। तालिका आत्म-संदर्भ है, और मैं यह समझने की कोशिश कर रहा हूं कि User.AddedByUser संपत्ति को उत्सुकता से लोड करने के लिए लिंक को एसक्यूएल कैसे प्राप्त करें, यानी जब भी User इकाई लोड/प्राप्त की जाती है, तो उसे उपयोगकर्ता भी प्राप्त करना होगा। AddedByUser और User.ChangedByUser । हालांकि, मैं समझता हूँ कि इस एक पुनरावर्ती समस्या बन सकता है ...

अद्यतन 1.1:

मैं इस प्रकार DataLoadOptions उपयोग करने के लिए कोशिश की है:

var options = new DataLoadOptions(); 
options.LoadWith<User>(u => u.ChangedByUser); 
options.LoadWith<User>(u => u.AddedByUser); 

db = new ModelDataContext(connectionString); 
db.LoadOptions = options; 

लेकिन यह नहीं है वस्तु ग्राफ अनुमति नहीं है -

System.InvalidOperationException occurred 
    Message="Cycles not allowed in LoadOptions LoadWith type graph." 
    Source="System.Data.Linq" 
    StackTrace: 
     at System.Data.Linq.DataLoadOptions.ValidateTypeGraphAcyclic() 
     at System.Data.Linq.DataLoadOptions.Preload(MemberInfo association) 
     at System.Data.Linq.DataLoadOptions.LoadWith[T](Expression`1 expression) 
     at i3t.KpCosting.Service.Library.Repositories.UserRepository..ctor(String connectionString) in C:\Development\KP Costing\Trunk\Code\i3t.KpCosting.Service.Library\Repositories\UserRepository.cs:line 15 
    InnerException: 

अपवाद काफी आत्म व्याख्यात्मक है: काम, मैं लाइन 2 पर निम्न अपवाद प्राप्त चक्रीय होना इसके अलावा, मानते हुए कि लाइन 2 ने अपवाद नहीं फेंक दिया, मुझे यकीन है कि लाइन 3 होगा, क्योंकि वे डुप्लिकेट कुंजी हैं।

अद्यतन 1.2:

निम्नलिखित या तो (साथ अद्यतन 1.1 ऊपर conjuction में इस्तेमाल नहीं किया) काम नहीं करता:

var query = from u in db.Users 
      select new User() 
      { 
       Id = u.Id, 
       // other fields removed for brevityy 
       AddedByUser = u.AddedByUser, 
       ChangedByUser = u.ChangedByUser, 

      }; 
return query.ToList(); 

यह निम्नलिखित, आत्म व्याख्यात्मक अपवाद फेंकता है:

System.NotSupportedException occurred 
Message="Explicit construction of entity type 'i3t.KpCosting.Shared.Model.User' in query is not allowed." 

अब मैं इसे हल करने के तरीके पर वास्तव में एक नुकसान पर हूं। कृपया सहायता कीजिए!

प्रश्न 2

मेरी DB में हर दूसरे की मेज पर है, और इसलिए एसक्यूएल मॉडल के लिए Linq, मैं दो क्षेत्रों, Entity.ChangedByUser और Entity.AddedByUser (Entity.ChangedByUserId विदेशी कुंजी/संबंध से जुड़ा हुआ) (Entity.AddedByUserId विदेशी कुंजी से लिंक किया गया/रिश्ते)

मैं इन क्षेत्रों को ईमानदारी से लोड करने के लिए लिंक से SQL कैसे प्राप्त करूं? क्या मुझे अपने प्रश्नों पर एक साधारण शामिल करने की ज़रूरत है ?, या कोई और तरीका है?

Linq to SQL eager loading on self referencing table http://img245.imageshack.us/img245/5631/linqtosql.jpg

उत्तर

3

शायद आप एक कदम वापस लेने का प्रयास कर सकते हैं और देख सकते हैं कि आप संबंध के साथ क्या करना चाहते हैं? मुझे लगता है कि आप इस जानकारी को उपयोगकर्ता को उदा। "8 घंटे पहले इयान गैलोवे द्वारा संशोधित"।

निम्नलिखित काम की तरह कुछ हो सकता है? : -

var users = from u in db.Users 
      select new 
      { 
       /* other stuff... */ 
       AddedTimestamp = u.AddedTimestamp, 
       AddedDescription = u.AddedByUser.FullName, 
       ChangedTimestamp = u.ChangedTimestamp, 
       ChangedDescription = u.ChangedByUser.FullName 
      }; 

मैं के लिए (IMO) स्पष्टता वहाँ एक गुमनाम प्रकार का उपयोग किया है। यदि आप चाहें तो आप उन गुणों को अपने उपयोगकर्ता प्रकार में जोड़ सकते हैं।

आपके दूसरे प्रश्न के लिए, आपका सामान्य लोडविथ (x => x.AddedByUser) इत्यादि ठीक काम करना चाहिए - हालांकि मैं डेटाबेस में विवरण स्ट्रिंग को सीधे संग्रहीत करना पसंद करता हूं - आपके पास एक व्यापार-बंद है ChangedByUser.FullName बदलते समय आपके विवरण को अद्यतन करते हुए और चेंजब्यूयूसर हटा दिए जाने पर कुछ जटिल और संभवतः counterintuitive करना पड़ता है (उदाहरण के लिए कैस्केड हटाएं, या अपने कोड में एक नल चेंजब्यूसर से निपटना)।

+0

हां, मैं अपनी जानकारी को अपने जीयूआई में प्रदर्शित करना चाहता हूं। मैं अज्ञात प्रकारों के उपयोग के बिना इस समस्या को हल करने की उम्मीद कर रहा था। लेकिन मुझे लगता है कि यह समस्या को हल करने का एक तरीका है। क्या मेरी समस्या लिंक से एसक्यूएल की कई रिश्तों से निपटने में असमर्थता से संबंधित है? –

+0

Na, आप उपयोगकर्ता को जोड़ सकते हैं। जोड़ा गया डिस्क्रिप्शन और उपयोगकर्ता। उपयोगकर्ता श्रेणी में चेंज डिस्क्रिप्शन फ़ील्ड और फिर आपको एक एनन प्रकार का उपयोग नहीं करना पड़ेगा। यह कई सारे रिश्तों के साथ वास्तव में कुछ भी नहीं है (आपके उदाहरण में प्रत्येक संबंध 1: 1 है)। यदि आप सीधे अपना एसक्यूएल लिख रहे थे, तो आप AddByUser के सभी गुणों को प्राप्त नहीं करना चाहते हैं (उनके जोड़ाबीयूसर सहित और अनंत में)। आप शायद अपने नाम के लिए अपना नाम और/या जो भी विवरण चाहते हैं उसे पकड़ लेंगे। इमो यह एक सामान्य सामान्य ओ/आरएम समस्या है। मुझे लगता है कि आपके पास एल 2 ई या हाइबरनेट के साथ एक ही समस्या होगी। –

0

सुनिश्चित नहीं हैं कि वहाँ Sql को Linq के साथ इस समस्या का समाधान है। यदि आप एसक्यूएल सर्वर 2005 का उपयोग कर रहे हैं तो आप एक (रिकर्सिव जैसे) संग्रहीत प्रोसेकडुर को परिभाषित कर सकते हैं जो आपके इच्छित परिणाम प्राप्त करने के लिए सामान्य तालिका अभिव्यक्तियों का उपयोग करता है और फिर DataContext.ExecuteQuery का उपयोग करके निष्पादित करता है।

4

Any type of cycles just aren't allowed। चूंकि LoadWith<T> या AssociateWith<T> संदर्भ पर हर प्रकार के लिए लागू होते हैं, इसलिए अंतहीन पाश को रोकने के लिए कोई आंतरिक तरीका नहीं है। अधिक सटीक रूप से, एसक्यूएल सर्वर को CONNECT BY और CTEs नहीं होने के कारण एसक्यूएल बनाने के तरीके पर यह उलझन में है कि लिंक वास्तव में प्रदान किए गए ढांचे के साथ स्वचालित रूप से जेनरेट कर सकता है।

आपके लिए उपलब्ध सबसे अच्छा विकल्प मैन्युअल रूप से 1 स्तर को बच्चों और गुमनाम प्रकार दोनों के लिए उपयोगकर्ता तालिका में शामिल करने के लिए मैन्युअल रूप से करना है। क्षमा करें यह एक साफ/आसान समाधान नहीं है, लेकिन यह वास्तव में लिंकक के साथ अब तक उपलब्ध है।

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