/ / जेनेरिक एक्सटेंशन विधि के भीतर एक स्ट्रिंग कॉलम नाम का उपयोग करके IQueryable को मल्टीसॉर्ट करना? - c #, एंटिटी-फ्रेमवर्क, लाइनक, रिफ्लेक्शन

एक सामान्य विस्तार विधि के भीतर एक स्ट्रिंग कॉलम नाम का उपयोग कर IQueryable multQueryorting? - सी #, इकाई-ढांचे, linq, प्रतिबिंब

मुझे कुछ कॉलम द्वारा संग्रह को क्रमबद्ध करने की आवश्यकता है। मेरे पास उन वस्तुओं की सूची है जहां हर ऑब्जेक्ट में कॉलमनाम और सॉर्टडायर (एस्क या डेस) हैं। तो, मैं इसे कैसे कर सकता हूं? मैंने इसे प्रतिबिंब द्वारा करने की कोशिश की है, लेकिन मेरे पास त्रुटि है:

Message: `LINQ to Entities does not recognize the method "Int32 Parse(System.String)" method, and this method cannot be translated into a store expression.`
StackTrace: `   at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.DefaultTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.EqualsTranslator.TypedTranslate(ExpressionConverter parent, BinaryExpression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input, DbExpressionBinding& binding)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, DbExpression& source, DbExpressionBinding& sourceBinding, DbExpression& lambda)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, DbExpression& source, DbExpressionBinding& sourceBinding, DbExpression& lambda)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.Convert()
at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__6()
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__5()
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0()
at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
at System.Linq.SystemCore_EnumerableDebugView`1.get_Items()`

मैंने कुछ लेख पढ़े इस तथा इस, लेकिन उनके समाधान मुझे मदद नहीं करते हैं। शायद किसी को मेरे लिए कुछ विचार है?

कोड:

public static IQueryable<T> SortByParams<T>(IQueryable<T> collection, List<SortBy> sorting)
{
bool firstOrder = true;
IOrderedQueryable<T> sortedRes = null;
foreach (SortBy sort in sorting)
{
try
{
if (firstOrder)
{
if (sort.sortDir.ToLower() == "desc")
{
sortedRes = collection.OrderByDescending(obj => obj.GetType().GetProperty(sort.columnName).GetValue(obj, null));
}
else
{
sortedRes = collection.OrderBy(obj => obj.GetType().GetProperty(sort.columnName).GetValue(obj, null));
}
firstOrder = false;
}
else
{
if (sort.sortDir.ToLower() == "desc")
{
sortedRes = sortedRes.ThenByDescending(obj => obj.GetType().GetProperty(sort.columnName).GetValue(obj, null));
}
else
{
sortedRes = sortedRes.ThenBy(obj => obj.GetType().GetProperty(sort.columnName).GetValue(obj, null));
}
}
}
catch (Exception) { }
collection = sortedRes;
}
return collection;
}

उत्तर:

उत्तर № 1 के लिए 1

भाव इस तरह

obj => obj.GetType().GetProperty(sort.columnName).GetValue(obj, null)

LINQ टू ऑब्जेक्ट्स संदर्भ में लागू हो सकता है, लेकिन निश्चित रूप से LINQ में एंटिटीज के लिए नहीं।

सामान्य तौर पर आप परावर्तन (और कई) का उपयोग नहीं कर सकते हैंLINQ के अंदर एंटिटीज़ क्वेरी अभिव्यक्ति के अन्य तरीके) क्योंकि वे एसक्यूएल में अनुवादित नहीं किए जा सकते (या क्वेरी प्रदाता उन्हें पहचानता नहीं है और उन्हें संभाल नहीं सकता है।) NotSupportedException)।

प्रतिबिंब के बजाय, आपको अभिव्यक्ति का उपयोग करना चाहिए System.Linq.Expressions.

उदाहरण के लिए, इस तरह:

public static IQueryable<T> SortByParams<T>(this IQueryable<T> source, List<SortBy> sorting)
{
var queryExpr = source.Expression;
string methodAsc = "OrderBy";
string methodDesc = "OrderByDescending";
foreach (var item in sorting)
{
var selectorParam = Expression.Parameter(typeof(T), "e");
var selector = Expression.Lambda(Expression.PropertyOrField(selectorParam, item.columnName), selectorParam);
var method = string.Equals(item.sortDir, "desc", StringComparison.OrdinalIgnoreCase) ? methodDesc : methodAsc;
queryExpr = Expression.Call(typeof(Queryable), method,
new Type[] { selectorParam.Type, selector.Body.Type },
queryExpr, Expression.Quote(selector));
methodAsc = "ThenBy";
methodDesc = "ThenByDescending";
}
return source.Provider.CreateQuery<T>(queryExpr);
}