2010-05-04 10 views
266

के साथ जुड़ता है/जहां मुझे लिंक और लैम्ब्डा में लिखी गई एक प्रश्न के साथ परेशानी हो रही है। अब तक, मैं त्रुटियों का एक बहुत हो रही है यहाँ मेरे कोड है:सी # लिंक/लैम्ब्डा

int id = 1; 
var query = database.Posts.Join(database.Post_Metas, 
           post => database.Posts.Where(x => x.ID == id), 
           meta => database.Post_Metas.Where(x => x.Post_ID == id), 
           (post, meta) => new { Post = post, Meta = meta }); 

LINQ का उपयोग करने के लिए मैं नई हूँ, इसलिए मुझे यकीन है कि अगर यह सही है क्वेरी नहीं कर रहा हूँ।

+6

में शामिल होने के लिए आप क्या हासिल करने की कोशिश कर रहे हैं? – GerManson

+2

आप एक वाक्य में क्या करना चाहते हैं? – hunter

+4

आपके मुख्य चयनकर्ता * रास्ता * बहुत जटिल हैं। यदि आप आईडी द्वारा चुनना चाहते हैं, तो बस x => x.ID ठीक है। –

उत्तर

616

मुझे लगता है कि यदि आप SQL सिंटैक्स से परिचित हैं, LINQ क्वेरी सिंटैक्स का उपयोग कर अधिक स्पष्ट, अधिक प्राकृतिक है, और यह आसान त्रुटियों को पहचानना बनाता है:

var id = 1; 
var query = 
    from post in database.Posts 
    join meta in database.Post_Metas on post.ID equals meta.Post_ID 
    where post.ID == id 
    select new { Post = post, Meta = meta }; 

तुम सच पर अटक कर रहे हैं हालांकि lambdas का उपयोग कर, आपका वाक्यविन्यास काफी दूर है। LINQ एक्सटेंशन विधियों का उपयोग करके, वही क्वेरी यहां दी गई है:

var id = 1; 
var query = database.Posts // your starting point - table in the "from" statement 
    .Join(database.Post_Metas, // the source table of the inner join 
     post => post.ID,  // Select the primary key (the first part of the "on" clause in an sql "join" statement) 
     meta => meta.Post_ID, // Select the foreign key (the second part of the "on" clause) 
     (post, meta) => new { Post = post, Meta = meta }) // selection 
    .Where(postAndMeta => postAndMeta.Post.ID == id); // where statement 
+4

@Emanuele Greco, आपके संपादन के संबंध में, "आईडी फ़ील्ड पर समानता जॉइन स्थिति में सेट है; आपको WHERE क्लॉज का उपयोग करने की आवश्यकता नहीं है!": WHERE क्लॉज आईडी फ़ील्ड के बीच समानता का परीक्षण नहीं कर रहा है, यह पोस्ट के बीच समानता का परीक्षण कर रहा है क्वेरी के बाहर घोषित आईडी कॉलम और आईडी पैरामीटर। –

+2

'लैम्ब्डा' का बहुत बढ़िया टुकड़ा और – ppumkin

+0

का उपयोग करने और समझने में आसान उद्धरण है, लिनक्स क्वेरी साफ़ करें। –

24

आपके मुख्य चयनकर्ता गलत हैं। उन्हें प्रश्न में तालिका के प्रकार का एक वस्तु लेनी चाहिए और शामिल होने के लिए कुंजी को वापस करना चाहिए। मुझे लगता है कि आपका मतलब यह है:

var query = database.Posts.Join(database.Post_Metas, 
           post => post.ID, 
           meta => meta.Post_ID, 
           (post, meta) => new { Post = post, Meta = meta }); 

आप बाद में कहां लागू कर सकते हैं, मुख्य चयनकर्ता के हिस्से के रूप में नहीं।

48

आप इसके साथ दो तरीकों से जा सकते हैं। LINQPad (अमूल्य यदि आप LINQ के लिए नए हैं) और एक डमी डेटाबेस का उपयोग करना, मैं निम्नलिखित प्रश्नों का निर्माण:

Posts.Join(
    Post_metas, 
    post => post.Post_id, 
    meta => meta.Post_id, 
    (post, meta) => new { Post = post, Meta = meta } 
) 

या

from p in Posts 
join pm in Post_metas on p.Post_id equals pm.Post_id 
select new { Post = p, Meta = pm } 

इस विशेष मामले में, मुझे लगता है कि LINQ वाक्यविन्यास क्लीनर है (मैं उन दोनों के बीच बदलता हूं जो पढ़ने के लिए सबसे आसान है)।

मैं जिस चीज को इंगित करना चाहता हूं वह यह है कि यदि आपके डेटाबेस में उचित विदेशी कुंजी हैं, (पोस्ट और पोस्ट_मेटा के बीच) तो आपको शायद एक स्पष्ट रूप से शामिल होने की आवश्यकता नहीं है जब तक कि आप लोड करने की कोशिश नहीं कर रहे हों बड़ी संख्या में रिकॉर्ड। आपका उदाहरण इंगित करता है कि आप एक ही पोस्ट और इसके मेटा डेटा को लोड करने का प्रयास कर रहे हैं।

var post = Posts.Single(p => p.ID == 1); 
var metas = post.Post_metas.ToList(); 

आप n + 1 समस्या से बचना चाहते हैं, तो आप स्पष्ट रूप से LINQ एसक्यूएल को बता सकते हैं संबंधित के सभी लोड करने के लिए: मान लिया जाये कि प्रत्येक पद के लिए कई post_meta रिकॉर्ड हैं कि, तो आप निम्न कर सकता है एक बार में आइटम (हालांकि यह एक उन्नत विषय हो सकता है जब आप L2S से अधिक परिचित हों)। उदाहरण नीचे कहते हैं, "जब आप एक पोस्ट लोड, जिसे 'Post_metas' संपत्ति के प्रतिनिधित्व वाले विदेशी कुंजी के माध्यम से इसके साथ जुड़े अपने रिकॉर्ड के सभी लोड":

var dataLoadOptions = new DataLoadOptions(); 
dataLoadOptions.LoadWith<Post>(p => p.Post_metas); 

var dataContext = new MyDataContext(); 
dataContext.LoadOptions = dataLoadOptions; 

var post = Posts.Single(p => p.ID == 1); // Post_metas loaded automagically 

यह एक पर कई LoadWith कॉल करने के लिए संभव है एक ही प्रकार के लिए DataLoadOptions का एकल सेट, या कई अलग-अलग प्रकार। यदि आप हालांकि बहुत कुछ करते हैं, तो आप कैशिंग पर विचार करना चाहेंगे।

+0

*** लिंककैड *** और ** सीआरएम 2016 **? – Kiquenet

2

ऐसा लगता है कि

var myvar = from a in context.MyEntity 
      join b in context.MyEntity2 on a.key equals b.key 
      select new { prop1 = a.prop1, prop2= b.prop1}; 
5

पोस्टिंग कुछ क्योंकि जब मैं LINQ + EntityFramework शुरू कर दिया, मैं एक दिन के लिए इन उदाहरणों को देखें हो सकता है।

यदि आप एंटीटीफ्रेमवर्क का उपयोग कर रहे हैं, और आपके पास नामक Meta नामक एक नेविगेशन प्रॉपर्टी है, तो यह गंदगी आसान है।यदि आप इकाई का उपयोग कर रहे हैं और उस नेविगेशन संपत्ति नहीं है, तो आप किसके लिए प्रतीक्षा कर रहे हैं?

database 
    .Posts 
    .Where(post => post.ID == id) 
    .Select(post => new { post, post.Meta }); 

आप कोड पहले कर रहे हैं, तो आप thusly संपत्ति सेट करेंगे:

class Post { 
    [Key] 
    public int ID {get; set} 
    public int MetaID { get; set; } 
    public virtual Meta Meta {get; set;} 
} 
8

डैनियल वाक्य रचना रिश्तों की एक अच्छी व्याख्या है, लेकिन मैं अपने टीम के लिए एक साथ इस दस्तावेज़ डाल उन्हें समझने के लिए इसे थोड़ा आसान बनाने के लिए। उम्मीद है कि यह enter image description here

1

इस linq क्वेरी को आपके लिए काम करना चाहिए। यह पोस्ट पोस्ट मेटा के सभी पद मिलेगा।

var query = database.Posts.Join(database.Post_Metas, 
           post => post.postId, // Primary Key 
           meta => meat.postId), // Foreign Key 
           (post, meta) => new { Post = post, Meta = meta }); 

समतुल्य एसक्यूएल क्वेरी

Select * FROM Posts P 
INNER JOIN Post_Metas pm ON pm.postId=p.postId 
1

मैं कुछ इस तरह किया है;

var certificationClass = _db.INDIVIDUALLICENSEs 
    .Join(_db.INDLICENSECLAsses, 
     IL => IL.LICENSE_CLASS, 
     ILC => ILC.NAME, 
     (IL, ILC) => new { INDIVIDUALLICENSE = IL, INDLICENSECLAsse = ILC }) 
    .Where(o => 
     o.INDIVIDUALLICENSE.GLOBALENTITYID == "ABC" && 
     o.INDIVIDUALLICENSE.LICENSE_TYPE == "ABC") 
    .Select(t => new 
     { 
      value = t.PSP_INDLICENSECLAsse.ID, 
      name = t.PSP_INDIVIDUALLICENSE.LICENSE_CLASS,     
     }) 
    .OrderBy(x => x.name); 
0

1 के बराबर होती है 1 दो अलग-अलग टेबल

 var query = 
      from post in database.Posts 
      join meta in database.Post_Metas on 1 equals 1 
      where post.ID == id 
      select new { Post = post, Meta = meta };