2009-02-16 13 views
16

मैं ईएफ आउट करने की कोशिश कर रहा हूं और कई रिश्तों के आधार पर मैं बहुत सारे फ़िल्टरिंग करता हूं। उदाहरण के लिए मेरे पास दो लिंक करने के लिए व्यक्तियों, स्थानों और एक व्यक्तिगत स्थान तालिका है। मेरे पास एक भूमिका और व्यक्तिगत तालिका भी है।इकाई ढांचे और कई प्रश्नों के लिए कई अनुपयोगी?

EDIT: Tables: 

Person (personid, name) 

Personlocation (personid, locationid) 

Location (locationid, description) 

Personrole (personid, roleid) 

Role (roleid, description) 

एफई मुझे व्यक्तियों, भूमिकाओं और स्थान संस्थाओं दे देंगे। संपादित करें: चूंकि ईएफ नहीं व्यक्तिगत स्थान और व्यक्तित्व इकाई प्रकार उत्पन्न करता है, इसलिए वे क्वेरी में उपयोग नहीं किए जा सकते हैं।

मुझे किसी दिए गए स्थान के साथ किसी दिए गए स्थान के सभी व्यक्तियों को देने के लिए मैं एक प्रश्न कैसे बना सकता हूं?

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

select p.* 
from persons as p 
join personlocations as pl on p.personid=pl.personid 
join locations  as l on pl.locationid=l.locationid 
join personroles  as pr on p.personid=pr.personid 
join roles   as r on pr.roleid=r.roleid 
where r.description='Student' and l.description='Amsterdam' 

मैं देखा है हो सकता है, लेकिन मैं एक सरल समाधान खोजने के लिए प्रतीत नहीं कर सकते हैं।

+1

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

उत्तर

11

लैम्ब्डा में:

var persons = Persons.Where(p=>(p.PersonLocations.Select(ps=>ps.Location) 
    .Where(l=>l.Description == "Amsterdam").Count() > 0) 
    && (p.PersonRoles.Select(pr=>pr.Role) 
    .Where(r=>r.Description == "Student").Count() > 0)); 

क्वेरी परिणाम:

SELECT [t0].[personId] AS [PersonId], [t0].[description] AS [Description] 
FROM [Persons] AS [t0] 
WHERE (((
    SELECT COUNT(*) 
    FROM [personlocations] AS [t1] 
    INNER JOIN [Locations] AS [t2] ON [t2].[locationid] = [t1].[locationid] 
    WHERE ([t2].[description] = @p0) AND ([t1].[personid] = [t0].[personId]) 
    )) > @p1) AND (((
    SELECT COUNT(*) 
    FROM [PersonRoles] AS [t3] 
    INNER JOIN [Roles] AS [t4] ON [t4].[roleid] = [t3].[roleid] 
    WHERE ([t4].[description] = @p2) AND ([t3].[personid] = [t0].[personId]) 
    )) > @p3) 

का उपयोग करना होता है():

var persons = Persons 
      .Where(p=>(p.Personlocations.Select(ps=>ps.Location) 
      .Select(l=>l.Description).Contains("Amsterdam")) && 
      (p.PersonRoles.Select(pr=>pr.Role) 
      .Select(r=>r.Description).Contains("Student"))); 

क्वेरी परिणाम:

SELECT [t0].[personId] AS [PersonId], [t0].[description] AS [Description] 
FROM [Persons] AS [t0] 
WHERE (EXISTS(
    SELECT NULL AS [EMPTY] 
    FROM [personlocations] AS [t1] 
    INNER JOIN [Locations] AS [t2] ON [t2].[locationid] = [t1].[locationid] 
    WHERE ([t2].[description] = @p0) AND ([t1].[personid] = [t0].[personId]) 
    )) AND (EXISTS(
    SELECT NULL AS [EMPTY] 
    FROM [PersonRoles] AS [t3] 
    INNER JOIN [Roles] AS [t4] ON [t4].[roleid] = [t3].[roleid] 
    WHERE ([t4].[description] = @p1) AND ([t3].[personid] = [t0].[personId]) 
    )) 

() में शामिल होने का उपयोग कर:

var persons = Persons 
     .Join(Personlocations, p=>p.PersonId, ps=>ps.Personid, 
(p,ps) => new {p,ps}) 
.Where(a => a.ps.Location.Description =="Amsterdam") 
     .Join(PersonRoles, 
pr=> pr.p.PersonId, r=>r.Personid,(pr,r) => new {pr.p,r}) 
.Where(a=>a.r.Role.Description=="Student") 
     .Select(p=> new {p.p}); 

क्वेरी परिणाम:

SELECT [t0].[personId] AS [PersonId], [t0].[description] AS [Description] 
FROM [Persons] AS [t0] 
INNER JOIN [personlocations] AS [t1] ON [t0].[personId] = [t1].[personid] 
INNER JOIN [Locations] AS [t2] ON [t2].[locationid] = [t1].[locationid] 
INNER JOIN [PersonRoles] AS [t3] ON [t0].[personId] = [t3].[personid] 
INNER JOIN [Roles] AS [t4] ON [t4].[roleid] = [t3].[roleid] 
WHERE ([t4].[description] = @p0) AND ([t2].[description] = @p1) 

आप चाहते हो सकता है परीक्षण जो एक तेजी से बड़े डेटा के साथ है।

शुभकामनाएं।

Giuliano Lemes

+2

। जॉइन (पर्सनलोकेशंस - हू? ईएफ कई से कई –

0

ठीक है, LINQ कोई प्रावधान नहीं जहाँ तक मैं बता सकता है। Lambda अभिव्यक्ति किसी भी() के साथ काम करते हैं।

29

नोट:

चूंकि यह एफई v1 में है, हम नहीं होगा PersonLocation और PersonRole जो नहीं है क्या LINQ2SQL करता है (domonstrating LINQ2SQL परिदृश्य ऊपर उत्तर की तरह संस्थाओं के रूप में उत्पन्न, । प्रश्न पर लागू होते हैं)

समाधान 1:

Persons.Include("Role").Include("Location") // Include to load Role and Location 
     .Where(p => p.Role.Any(r => r.description == "Student") 
     && p.Location.Any(l => l.description == "Amsterdam")).ToList(); 

यह अच्छा और सीधा दिखता है, लेकिन यह बदसूरत एसक्यूएल स्क्रिप्ट उत्पन्न करता है और इसका प्रदर्शन ठीक है।

समाधान 2:

यहाँ ब्रेकडाउन कर रहे हैं।

// Find out all persons in the role 
    // Return IQuerable<Person> 
    var students = Roles.Where(r => r.description == "Student") 
         .SelectMany(r => r.Person); 

    // Find out all persons in the location 
    // Return IQuerable<Person> 
    var personsInAmsterdam = Locations.Where(l=> l.description == "Amsterdam") 
            .SelectMany(l=>l.Person); 

    // Find out the intersection that gives us students in Admsterdam. 
    // Return List<Person> 
    var AdmsterdamStudents = students.Intersect(personsInAmsterdam).ToList(); 

एक में ऊपर तीन चरणों संयुक्त करें:

//Return List<Person> 
var AdmsterdamStudents = Roles.Where(r => r.description == "Student") 
           .SelectMany(r => r.Person) 
           .Intersect 
           ( 
           Locations 
           .Where(l=> l.description == "Amsterdam") 
           .SelectMany(l=>l.Person) 
           ).ToList(); 

यह एक तरह से वर्बोज़ है। लेकिन यह स्वच्छ एसक्यूएल क्वेरी उत्पन्न करता है और अच्छी तरह से प्रदर्शन करता है।

+0

ग्रेट उत्तर के लिए यह उत्पन्न नहीं करेगा, ईएफ के साथ भी काम करता है जहां यहां स्वीकृत उत्तर ईएफ – Paul

+0

के साथ काम नहीं करता है चिपचिपा समस्या का वास्तव में शानदार जवाब। –

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