c# - इकाई ढांचा IQueryable विस्तार विधियाँ उप क्वेरी के रूप में काम नहीं करते हैं




entity-framework linq (2)

मैं जहां तक ​​संभव हो वहां विस्तार विधियों का उपयोग करके अपने प्रश्नों को लिखना चाहता हूं। तो निम्नलिखित एक क्वेरी है जो मेरे लिए काम करती है:

int studentId = 
    (
        from u in db.Users
            .FromOrganisation(org.Id)
            .IsStudent()
            .IsActive()
        where u.ExtId == dto.StudentExtId
        select u.Id
    ).FirstOrDefault();

विस्तार विधियां इस प्रकार हैं:

public static IQueryable<User> IsStudent(this IQueryable<User> u)
{
    return u.Where(x => x.Type == (int)UserTypes.Student);
}

हालांकि, जब मैं उप-क्वेरी में एक्सटेंशन विधियों का उपयोग करता हूं, तो मुझे निम्न संदेश मिलता है:

लिनक्यू को यूनिट्स 'सिस्टम.लिंक। आईक्यूरेबल' 1 [eNotify.Domain.Models.User] आईएसएक्टिव (सिस्टम.लिंक। आईक्यूरेबल '1 [eNotify.Domain.Models.User])' विधि, और इस पद्धति को नहीं पहचानती है किसी स्टोर की अभिव्यक्ति में अनुवाद नहीं किया जा सकता

यहां वह क्वेरी है जो उस संदेश का कारण बनती है:

var vm = from o in db.Organisations
         select new StaffStudentVm
         {
             StudentId = (
                 from u in db.Users
                     .FromOrganisation(org.Id)
                     .IsStudent()
                     .IsActive()
                 where u.ExtId == dto.StudentExtId
                 select u.Id
                 ).FirstOrDefault(),
             StaffId = (
                 from u in db.Users
                     .FromOrganisation(org.Id)
                     .IsStaff()
                     .IsActive()
                 where u.ExtId == dto.StaffExtId
                 select u.Id
                 ).FirstOrDefault()
         };

return vm.FirstOrDefault();

मैं क्या गलत कर रहा हूं?

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


मैंने अंततः इसे GitHub पर इकाई फ़्रेमवर्क टीम के साथ उठाया आप थ्रेड को यहां क्यों देख सकते हैं, इसका पूरा विवरण यहां देख सकते हैं:

https://github.com/aspnet/EntityFramework6/issues/98

ऐसा लगता है कि ईएफ 6.2 में शामिल करने के लिए एक सुझाव के रूप में उठाया गया था, लेकिन तब तक, एक बहुत खूबसूरत काम-आसपास का सुझाव दिया गया था। आप इसे धागा में पढ़ सकते हैं, लेकिन मैंने इसे त्वरित संदर्भ के लिए यहां कॉपी किया है।

यहां मूल क्वेरी है (जहां एक उप-क्वेरी में उपयोग किया जा रहा IQueryable विस्तार विधि के कारण त्रुटि उत्पन्न होती है):

var vm = from o in db.Organisations
         select new StaffStudentVm
         {
             StudentId = (
                 from u in db.Users
                     .FromOrganisation(org.Id)
                     .IsStudent()
                     .IsActive()
                 where u.ExtId == dto.StudentExtId
                 select u.Id
                 ).FirstOrDefault(),
             StaffId = (
                 from u in db.Users
                     .FromOrganisation(org.Id)
                     .IsStaff()
                     .IsActive()
                 where u.ExtId == dto.StaffExtId
                 select u.Id
                 ).FirstOrDefault()
         };

return vm.FirstOrDefault();

और यहां यह लिखना है कि कोई त्रुटि नहीं होती है:

var stuList = db.Users.FromOrganisation(org.Id).IsStudent().IsActive();
var staffList = db.Users.FromOrganisation(org.Id).IsStaff().IsActive();

var vm = from o in db.Organisations
         select new StaffStudentVm
         {
             StudentId = (
                 from u in stuList
                 where u.ExtId == dto.StudentExtId
                 select u.Id
                 ).FirstOrDefault(),
             StaffId = (
                 from u in staffList
                 where u.ExtId == dto.StaffExtId
                 select u.Id
                 ).FirstOrDefault()
         };

return vm.FirstOrDefault();

मैं पुष्टि कर सकता हूं कि यह शैली अभी भी केवल 1 राउंड ट्रिप में डेटाबेस के लिए परिणाम है। कई बयानों में क्वेरी को तोड़ने से वास्तव में बहुत से स्थानों में भी पठनीयता में सुधार होता है


आप अपने User मॉडल के लिए एक आंशिक कक्षा बना सकते हैं जिसमें एक स्थैतिक कक्षा होती है:

partial class User
{
    public static class Q
    {
        public static Expression<Func<User,bool>> IsStudent
        {
            return x => x.Type == (int)UserTypes.Student;
        }
    }
}

फिर आपकी क्वेरी इस तरह दिखाई देगी:

var vm = from o in db.Organisations
     select new StaffStudentVm
     {
         StudentId = (
             from u in db.Users
                 .FromOrganisation(org.Id)
                 .Where(User.Q.IsStudent)
                 .IsActive()
             where u.ExtId == dto.StudentExtId
             select u.Id
             ).FirstOrDefault(),
         StaffId = (
             from u in db.Users
                 .FromOrganisation(org.Id)
                 .IsStaff()
                 .IsActive()
             where u.ExtId == dto.StaffExtId
             select u.Id
             ).FirstOrDefault()
     };

यह विस्तार विधियों के रूप में सुरुचिपूर्ण नहीं है, लेकिन मुझे लगता है कि यह चाल करना चाहिए ...





entity-framework-6