LINQ إلى SQL تجميع الاستعلام المشكلة (يعمل غير المجمعة الاستعلام)

StackOverflow https://stackoverflow.com/questions/1420672

سؤال

لدي C# طرق الإرشاد على IQueryable, مثلا FindNewCustomers() و FindCustomersRegisteredAfter(int year) وما الذي يمكنني استخدام "سلسلة" استعلام معا من أجل LINQ to SQL.

الآن مشكلتي:أريد إنشاء تجميع الاستفسارات على سبيل المثال:

 private static Func<MyDataContext, SearchInfo, IQueryable<Customer>>
        CQFindAll = 
            CompiledQuery.Compile((MyDataContext dc, SearchInfo info) =>
                dc.Contacts.Select(c => c).FindCustomersRegisteredAfter(info.RegYear)
                           .OrderBy(info.OrderInfo)
                           .Skip(info.SkipCount)
                           .Take(info.PageSize));

على FindCustomersRegisteredAfter(int year) الأسلوب هو امتداد طريقة أخذ IQueryable والعودة نفس.على OrderBy الأسلوب هو طريقة تمديد وكذلك (نظام.Linq.ديناميكية) مما يخلق دينامية التعبير على أساس سلسلة (على سبيل المثال"الاسم الأول ASC" سيتم فرز حقل الاسم الأول تصاعدي). Skip و Take هي المدمج في الأساليب.

أعلاه (لا كما جمعت الاستعلام ، ولكن العادية الاستعلام) يعمل مثالية.مرة واحدة وضعت في تجميع الاستعلام أنا ضربت الخطأ التالية:

الأسلوب 'النظام.Linq.IQueryable`1[المجال.العملاء] FindCustomersRegisteredAfter[العملاء](System.Linq.IQueryable`1[المجال.العملاء] Int32)' لا يوجد لديه دعم الترجمة إلى SQL.

مرة أخرى ، هذا يعمل تماما إذا كان الاستعلام غير المترجمة, فقط منتظم استعلام LINQ.يظهر الخطأ مرة واحدة فقط ومن داخل CompiledQuery.ترجمة().

تساعد؟؟!

تحرير:إن إنشاء الاستعلام عبر فار الاستعلام = (...) بنفس الطريقة داخل CompiledQuery.تجميع هذه SQL التي تم إنشاؤها:

SELECT [t1].[Id], [t1].[FirstName], [t1].[LastName], 
       [t1].[RegYear], [t1].[DeletedOn]
FROM (
 SELECT ROW_NUMBER() OVER (ORDER BY [t0].[LastName]) AS [ROW_NUMBER], 
        [t0].[Id], [t0].[FirstName], [t0].[LastName], [t0].[RegYear], 
        [t0].[DeletedOn]
FROM [dbo].[Contacts] AS [t0]
WHERE ([t0].[RegYear] > @p0) AND ([t0].[DeletedOn] IS NULL)
     ) AS [t1]
WHERE [t1].[ROW_NUMBER] BETWEEN @p1 + 1 AND @p1 + @p2
ORDER BY [t1].[ROW_NUMBER]

لذلك ترى أن SQL هو كل شيء تماما للترجمة بحيث لا تحتاج فقط لملء في @p0, @p1 @p2 لهذا العمل مرارا وتكرارا!ما هو الخطأ مع CompiledQuery.تجميع?!?

تحديث:أنا أفهم أن OrderBy لا يمكن العمل (كما انها ليست @p المعلمة).أنا لا تزال تحاول معرفة لماذا CompiledQuery.الترجمة لا تعمل مع طرق الإرشاد على الرغم من.المعلومات على شبكة الإنترنت أن هذا الموضوع هو تقريبا غير موجودة.

هل كانت مفيدة؟

المحلول

أعتقد أن تجميع الاستعلام يجب أن يكون للترجمة إلى SQL والتي طريقة التمديد لا يمكن أن يكون.إذا كنت التعريف SQL التي تم إنشاؤها بواسطة "العادية" الاستعلام قد تجد أنه هو تحديد الجدول بأكمله لذلك يمكن تغذية جميع الصفوف في طريقة التمديد.

من الأفضل لك أن تضع منطق تصفية في الاستعلام (كجزء من شجرة التعبير) لذلك يمكن أن تترجم إلى SQL و تشغيل الملقم.

على OrderBy هو أيضا مشكلة بسبب تخطي.تحتاج إلى جعل هذا للترجمة إلى SQL أو ينق سوف تضطر إلى إعادة جميع الصفوف من أجل تصفية عليهم من جانب العميل.

إذا كنت لا تستطيع التعبير عن هذه كما ينق التعبير النظر في خلق وظائف SQL على الملقم ورسم لهم DataContext.LINQ سوف تكون قادرة على ترجمة تلك T-SQL المكالمات وظيفة.

تحرير:

أعتقد أنني كنت على افتراض امتداد الطرق لم تكن بناء أشجار التعبير.آسف.

النظر في هذا الرابط والتي تبدو مشابهة لمشكلتك.ومن مراجع أخرى الرابط أن يذهب إلى مزيد من التفاصيل.

يبدو أن MethodCallExpression هو المشكلة.

رمز هو طويل قليلا ليتم نشرها هنا, ولكن على غرار tomasp.net's المتوسع ، أقوم بزيارة كل تعبير في شجرة التعبير و إذا كانت العقدة هي أ MethodCallExpression الذي يدعو طريقة إرجاع تعبير شجرة أنا الاستعاضة عن ذلك MethodCallExpression من التعبير شجرة إرجاعها بواسطة استدعاء الأسلوب.

لذا يبدو أن المشكلة هي أنه عند تجميع الاستعلام طريقة يتم تنفيذ ذلك حتى لا يكون هناك أي شجرة التعبير أن تترجم إلى SQL.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top