2012-07-23 17 views
8

निम्न तालिका संरचना के साथ (बाहरी हटाया कॉलम)को शामिल करें और कहाँ विधेय कारण में शामिल होने के बजाय आंतरिक

create table [Events] 
(
    ID int not null identity, 
    Name nvarchar(128) not null, 
    constraint PK_Events primary key(ID) 
) 

create table [Donations] 
(
    ID int not null identity, 
    EventID int not null, 
    Amount decimal(10, 2) not null, 

    constraint PK_Donations primary key(ID), 
    constraint FK_Donations_Events foreign key(EventID) references [Events](ID) on update no action on delete no action 
) 

मैं निम्नलिखित Linq करने वाली संस्थाओं प्रश्नों का उपयोग में शामिल होने के लिए छोड़ दिया:

// 1 
ents.Donations.Where(d => d.Amount > 25.0m && d.Event.Name.Contains("Run")).ToList(); 

// 2 
ents.Donations.Include("Event").Where(d => d.Amount > 25.0m).ToList(); 

// 3 
ents.Donations.Include("Event").Where(d => d.Amount > 25.0m && d.Event.Name.Contains("Run")).ToList(); 

का उत्पादन (एक SQL प्रोफाइलर से):

-- 1 
SELECT 
[Extent1].[ID] AS [ID], 
[Extent1].[EventID] AS [EventID], 
[Extent1].[Amount] AS [Amount] 
FROM [dbo].[Donations] AS [Extent1] 
INNER JOIN [dbo].[Events] AS [Extent2] ON [Extent1].[EventID] = [Extent2].[ID] 
WHERE ([Extent1].[Amount] > 25.0) AND ([Extent2].[Name] LIKE N'%Run%') 

-- 2 
SELECT 
[Extent1].[ID] AS [ID], 
[Extent1].[EventID] AS [EventID], 
[Extent1].[Amount] AS [Amount], 
[Extent2].[ID] AS [ID1], 
[Extent2].[Name] AS [Name] 
FROM [dbo].[Donations] AS [Extent1] 
INNER JOIN [dbo].[Events] AS [Extent2] ON [Extent1].[EventID] = [Extent2].[ID] 
WHERE [Extent1].[Amount] > 25.0 

-- 3 
SELECT 
[Extent1].[ID] AS [ID], 
[Extent1].[EventID] AS [EventID], 
[Extent1].[Amount] AS [Amount], 
[Extent3].[ID] AS [ID1], 
[Extent3].[Name] AS [Name] 
FROM [dbo].[Donations] AS [Extent1] 
INNER JOIN [dbo].[Events] AS [Extent2] ON [Extent1].[EventID] = [Extent2].[ID] 
LEFT OUTER JOIN [dbo].[Events] AS [Extent3] ON [Extent1].[EventID] = [Extent3].[ID] 
WHERE ([Extent1].[Amount] > 25.0) AND ([Extent2].[Name] LIKE N'%Run%') 

क्यों 3 क्वेरी में, यह एकउत्पन्न करता है Events टेबल पर दूसरी बार 0? जबकि क्वेरी सही परिणाम उत्पन्न करती है, यह अजीब लगता है, क्यों EF/LINQ [Extent2]SELECT और WHERE खंड में फिर से उपयोग नहीं कर सकता है, और यह LEFT OUTER JOIN क्यों है?

मैं विजुअल स्टूडियो 2010 एसपी 1 .NET 4 का उपयोग कर रहा हूं और मैं एसक्यूएल सर्वर 2008 एक्सप्रेस से कनेक्ट कर रहा हूं।

उत्तर

6

बाएं जुड़ने के लिए यह सुनिश्चित करना होगा कि दान तालिका से कोई पंक्ति गायब न हो, इस मामले में दान एक ऐसी घटना को इंगित करता है जो मौजूद नहीं है। वे नहीं चाहते हैं कि कीवर्ड को मूल तालिका से पंक्तियों को गायब होने का दुष्प्रभाव हो, ताकि वे सुरक्षा के लिए बाएं जुड़ने का उपयोग कर सकें।

तालिका को दो बार शामिल करने के संबंध में यह शायद ईएफ की एक सीमा है। आप अपनी क्वेरी में इसे दो बार उल्लेख करते हैं और अनुकूलन करने के लिए पर्याप्त स्मार्ट नहीं है।

मुझे यह कहना है कि यदि आप एसक्यूएल अनुकूलित करना चाहते हैं तो एसक्यूएल लिखें, ईएफ से परेशान न हों। आप जो कर रहे हैं उसकी तुलना डीकंपलिंग सी # से की जा सकती है और पूछना चाहिए कि असेंबलर के पास कुछ निश्चित अनुकूलन क्यों नहीं है। आप का उपयोग करते हैं एफई तो अपनी आँखें बंद करने के लिए क्या SQL यह आपके सवाल का :-)

+1

दूसरी क्वेरी 'Include' का उपयोग करती है फिर भी बाएं शामिल नहीं होती है। – Matthew

+0

बहुत अच्छा सवाल है, मैंने यह नहीं देखा। यह मेरे सामने वापस प्रतीत होता है। दूसरी क्वेरी में बाएं शामिल होना चाहिए ताकि इसमें साइड इफेक्ट्स न हो और तीसरी क्वेरी में आंतरिक शामिल होना चाहिए क्योंकि इसे किसी इवेंट पंक्ति की आवश्यकता है। – MikeKulls

+0

एक बाएं जुड़ाव समझ में आता है अगर यह एक नामुमकिन कॉलम था, या अगर मेरे पास रेफरेंसियल अखंडता नहीं थी। – Matthew

0

प्रत्यक्ष नहीं जवाब पैदा करता है, लेकिन एक प्रयास अन्य जवाब के लिए अपनी टिप्पणी को पढ़ने के बाद आपको सही दिशा में बात करने के लिए:

आपके पास कुछ ओआरएम यूएसएस (सहित ईएफ) की रक्षा करने के लिए आवश्यक सब कुछ है - एसपी की मात्रा और गुणवत्ता के बारे में आपने यही कहा है। किसी भी दृष्टिकोण में शुद्ध एसक्यूएल समेत समस्याएं होंगी, यदि वह वर्ग अच्छी तरह लिखित या बनाए रखने में कठोर नहीं है।

इसलिए, यदि कुछ ओआरएम (ईएफ, आदि) कभी-कभी गैर-कुशल कोड उत्पन्न करते हैं, और यह वास्तव में प्रदर्शन समस्याओं का कारण बनता है, तो यह "आवश्यकता" बन जाता है, और एसपी का उपयोग करके भी हल किया जाना चाहिए।

तो, व्यवसाय परिप्रेक्ष्य से अपनी समस्याओं को देखें - आपके पास खराब संरचित और संग्रहित प्रक्रियाओं के समूह को बनाए रखने के लिए कठिन है। शायद आपकी अधिकांश टीम सी # है और एसक्यूएल डेवलपर्स नहीं है।

ओआरएम का उपयोग कोड आधार की रखरखाव में वृद्धि करेगा, साथ ही सी # में सभी टीम सदस्यों की विशेषज्ञता के बेहतर उपयोग की अनुमति देगा।

कुछ विशिष्ट अवसरों पर ओआरएम द्वारा उत्पादित खराब एसक्यूएल कोड, तकनीक का उपयोग करने के लिए शायद ही कभी "नहीं जाना" है, जब तक साबित न हो कि यह मौजूदा लोगों को हल करने से अधिक समस्याएं पैदा करेगा।

+0

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

+0

वे निश्चित रूप से एसक्यूएल में अनुभवहीन नहीं हैं, एप्लिकेशन निरंतर विकास के 9 साल (एएसपीनेट 1.0 के साथ शुरू हुआ), कई अलग-अलग डेवलपर्स के माध्यम से चला गया है। जिस आवेदन के रूप में यह अभी खड़ा है, उसके पास चिंताओं का कोई अलगाव नहीं है, संग्रहित प्रो को सीधे कोड के अंदर बुलाया जा रहा है। यही कारण है कि मैं ऐसा कुछ ढूंढ रहा हूं जो प्रबंधित करना बहुत आसान हो, क्योंकि ज्यादातर मेरा मानना ​​है कि संग्रहीत प्रोसेस का संगठन अभी लिखना बंद है। – Matthew

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