How to get skip size and query paramtere for get all method using dictionary - dictionary

public async Task<List<DrugModel>> GetAllDrugs(int take, int skip, string query)
{
var data = Drugs.ToDictionary(x=>x
var result = Drugs.Skip(skip).Take(take).Where(x => x.Value.AtcCode == query || x.Value.Name == query || x.Value.SuklCode == query).ToList();
return data;
}
i want to use it with dictionary
because on top of the grain i pass
private IDictionary<string,DrugModel> Drugs { get; set; } = new Dictionary<string, DrugModel>();
i did it as sp but i want it query values as list in dictionary

Related

is it a good idea to do transformation in a database model with ASP.Net

we are a small development team.
We develop in ASP.NET and we are starting to use generic controllers and services.
The goal is to have solid methods for things that are repetitive.
What we ask ourselves is if it is a good idea to do some transformation in the data models to allow us to reuse our functions that we know are working?
Exemple: we have a combobox and we want to manage the display and search. It's always the same and redundant.
This is my class
[Table("stage.Test")]
public partial class Test : IBaseEntity, ICombobox
{
public virtual Product Product { get; set; }
public string nom { get; set; }
public string prenom { get; set; }
public string title { get; set; }
[NotMapped]
public virtual string AffichageCombobox => nom + prenom;
[NotMapped]
public virtual string TexteRecherche => Product.Gabarit.Description;
}
as you can see i have two columns with the tag [NotMapped]. These are the columns in the interface ICombobox
public interface ICombobox
{
string AffichageCombobox { get;}
string TexteRecherche { get; }
}
this is the first service where I use one of my two columns which redirects to other columns. [We use the column "AffichageCombobox" from the model]
public List<ComboboxViewModel> GetComboboxViewModel(int? id, bool actifseulement, string text)
{
var query = _requestDatabaseService.GetComboboxQuery<T>(id, actifseulement, text);
var list = query.Select(table => new ComboboxViewModel
{
Id = table.Id,
AffichageCombobox = table.DateHFin == null ? table.AffichageCombobox : table.AffichageCombobox + " (inactif)"
}).ToList();
return list;
}
This is the RequestDatabaseService [We use the column "TexteRecherche" from the model]
public List<T> GetComboboxQuery<T>(int? id, bool actifseulement, string text) where T : class, IBaseEntity, ICombobox
{
text = text.ToLower();
var list = _dbContext.Set<T>()
.If(id.HasValue,
q => q.Where(x => x.Id == id))
.If(actifseulement,
q => q.Where(x => x.DateHFin == null))
.If(text != "",
q => q.Where(x => x.TexteRecherche.ToLower() == text))
.ToList();
return list;
}
As you can see, I am using an interface to add columns to redirect to the correct columns to my data model to avoid overriding my methods for two column.
Is it a good idea, a good practice ?
What do you think is the best practice if we want to do generic functions, but the columns are not called the same way?
Thank you!
Your solution has a lot of weaknesses
You have extended Model to handle specific UI cases. In my opinion it is bad practice.
Your virtual properties will not work in LINQ query. EF translates only Expression because it canot look into compiled property body.
What we can do here is simplifying of building such comboboxes. I have defind set fo extensions which can be reused for such scenarios. Sorry if there some mistakes, written from memory.
How it can be used:
Assuming that GetComboboxViewModel is not in generic class
public List<ComboboxViewModel> GetComboboxViewModel(int? id, bool actifseulement, string text)
{
// uncover DbContext. All that we need is IQueryable<Test>
var ctx = _requestDatabaseService.GetContext();
var query = ctx.Test.AsQueryable();
var comboItems = query
.FilterItems(id, actifseulement)
.GetComboboxQuery(text, e => e.Product.Gabarit.Description, e => e.nom + e.prenom)
.ToList();
return comboItems;
}
Think about this solution and yes, we can register somewhere pair of Lmbdas Dictionary<Type, (LambdaExpression: searchProp, LambdaExpression: displayProp)> and dynamically build call above.
Realisation:
public static class QueryableExtensions
{
// more simlified version for filtering
public static IQueryable<T> WhereIf(this IQueryable<T> query, bool condition, Expression<Func<T, bool>> predicate)
{
return condition ? query.Where(predicate) : query;
}
// handy function for filtering
public static IQueryable<T> FilterItems<T>(this IQueryable<T> query, int? id, bool onlyActive)
where T : IBaseEntity
{
query = query
.WhereIf(id.HasValue, x => x.Id == id)
.WhereIf(onlyActive, x => x.DateHFin == null)
return query;
}
// dynamic generation of filtering and projection
public static IQueryable<ComboboxViewModel> GetComboboxQuery<T>(this IQueryable<T> query, string text, Expression<Func<T, string>> searchProp, Expression<Func<T, string>> dsiplayProp)
where T : IBaseEntity
{
if (!string.IsNullOrEmpty(text))
{
text = text.ToLower();
// defining search pattern
// this also extension point, you may use here `Contains` or FullText search functions
Expression<Func<string, string, bool>> filterFunc = (s, t) => s.ToLower() == t;
// reusing parameter from searchProp lambda
var param = searchProp.Parameters[0];
// applying pattern to searchprop
var filterBody = ExpressionReplacer.GetBody(filterFunc, searchProp.Body, Expression.Constant(text));
// applying generated filter
var filterPredicate = Expression.Lambda<Func<T, bool>>(filterBody, param);
query = query.Where(filterPredicate);
}
// defining template for Select
Expression<Func<T, string, ComboboxViewModel>> createTemplate = (entity, dp) => new ComboboxViewModel
{
Id = entity.Id,
AffichageCombobox = entity.DateHFin == null ? dp : dp + " (inactif)"
};
// reusing parameter from dsiplayProp lambda
var entityParam = dsiplayProp.Parameters[0];
// injecting dsiplayProp into createTemplate
var selectBody = ExpressionReplacer.GetBody(createTemplate, entityParam, dsiplayProp.Body);
var selectLambda = Expression.Lambda<Func<T, ComboboxViewModel>>(selectBody, entityParam);
// applying projection
var comboQuery = query.Select(selectLambda);
return comboQuery;
}
// helper class for correcting expressions
class ExpressionReplacer : ExpressionVisitor
{
readonly IDictionary<Expression, Expression> _replaceMap;
public ExpressionReplacer(IDictionary<Expression, Expression> replaceMap)
{
_replaceMap = replaceMap ?? throw new ArgumentNullException(nameof(replaceMap));
}
public override Expression Visit(Expression exp)
{
if (exp != null && _replaceMap.TryGetValue(exp, out var replacement))
return replacement;
return base.Visit(exp);
}
public static Expression Replace(Expression expr, Expression toReplace, Expression toExpr)
{
return new ExpressionReplacer(new Dictionary<Expression, Expression> { { toReplace, toExpr } }).Visit(expr);
}
public static Expression Replace(Expression expr, IDictionary<Expression, Expression> replaceMap)
{
return new ExpressionReplacer(replaceMap).Visit(expr);
}
public static Expression GetBody(LambdaExpression lambda, params Expression[] toReplace)
{
if (lambda.Parameters.Count != toReplace.Length)
throw new InvalidOperationException();
return new ExpressionReplacer(Enumerable.Range(0, lambda.Parameters.Count)
.ToDictionary(i => (Expression) lambda.Parameters[i], i => toReplace[i])).Visit(lambda.Body);
}
}
}
Well, after writing this sample, I think, it can be cardinally simplified by using LINQKit. Will post another answer with LINQKit usage if you are interested,

.NET MVC Linq pagination with PagedList

In my MVC app I'm using LINQ to retrieve data from DB and PagedList for pagination. I have a couple of questions, after the code block, that I would like some help with.
Function where I retrieve data from cache or DB:
public NewsPagedListDTO GetNewsFromCacheOrDB(int pageSize, int? newsID, int? page, string newsTitle, int? categoryID, int? orderByTitle, int? orderByPublisher, int? orderByDate, int? orderByCategory)
{
DataCache cache = new DataCache("default");
object cacheNews = cache.Get("cacheNews");
List<News> news = new List<News>();
if (cacheNews == null)
{
news = (from n in DB.News
select n).ToList();
//Only cache if no parameters was provided
if (newsID == null && newsTitle == null && categoryID == null && orderByTitle == null && orderByPublisher == null &&
orderByDate == null && orderByCategory == null)
cache.Add("cacheNews", news);
}
}
else
{
news = (List<News>)cacheNews;
}
if (newsID != null)
news = news.Where(n => n.NewsID == newsID).ToList();
if (categoryID != null)
news = news.Where(n => n.CategoryID == categoryID).ToList();
if (newsTitle != null)
news = news.Where(n => n.Title == newsTitle).ToList();
if (orderByTitle != null)
if (orderByTitle == 0)
news = news.OrderBy(n => n.Title).ToList();
else
news = news.OrderByDescending(n => n.Title).ToList();
if (orderByPublisher != null)
if (orderByPublisher == 0)
news = news.OrderBy(n => n.PublishedByFullName).ToList();
else
news = news.OrderByDescending(n => n.PublishedByFullName).ToList();
if (orderByDate != null)
if (orderByDate == 0)
news = news.OrderByDescending(n => n.DatePublished).ToList();
else
news = news.OrderBy(n => n.DatePublished).ToList();
if (orderByCategory != null)
if (orderByCategory == 0)
news = news.OrderBy(n => n.CategoryToString).ToList();
else
news = news.OrderByDescending(n => n.CategoryToString).ToList();
List<NewsDTO> newsDTO = new List<NewsDTO>();
foreach (var item in news)
{
NewsDTO newsDTOtemp = new NewsDTO();
newsDTOtemp.BlobName = item.BlobName;
newsDTOtemp.DatePublished = item.DatePublished;
newsDTOtemp.NewsID = item.NewsID;
newsDTOtemp.PreviewText = item.PreviewText;
newsDTOtemp.PublishedByEmail = item.PublishedByEmail;
newsDTOtemp.PublishedByFullName = item.PublishedByFullName;
newsDTOtemp.PublishedByID = item.PublishedByID;
newsDTOtemp.Title = item.Title;
newsDTOtemp.CategoryID = item.Category.CategoryID;
newsDTOtemp.CategoryToString = item.Category.Name;
newsDTO.Add(newsDTOtemp);
}
//Pagination
NewsPagedListDTO newsResultDTO = new NewsPagedListDTO();
newsResultDTO.NewsDTO = (PagedList<NewsDTO>)newsDTO.ToPagedList(page ?? 1, pageSize);
return newsResultDTO;
}
Pagination in my view:
#Html.PagedListPager(Model.NewsPagedListDTO.NewsDTO, page => Url.Action("News", new
{
page,
newsTitle = Request.QueryString["NewsTitle"],
categoryID = Request.QueryString["categoryID"],
orderByTitle = Request.QueryString["orderByTitle"],
orderByPublisher = Request.QueryString["orderByPublisher"],
orderByDate = Request.QueryString["orderByDate"],
orderByCategory = Request.QueryString["orderByCategory"]
}),
new PagedListRenderOptions()
{
Display = PagedListDisplayMode.IfNeeded,
MaximumPageNumbersToDisplay = 5,
DisplayEllipsesWhenNotShowingAllPageNumbers = false,
DisplayLinkToPreviousPage = PagedListDisplayMode.Never,
DisplayLinkToNextPage = PagedListDisplayMode.Never,
LinkToFirstPageFormat = String.Format("«"),
LinkToLastPageFormat = String.Format("»")
})
Questions
It's the first time I'm using PagedList. What's the point in having postback for changing the page when the full results is retrieved? Isn't it better with client side pagination then? Currently I am retrieving all posts from DB with:
news = (from n in DB.News
select n).ToList();
And after data is retrieved, sort with parameters..
Sure the result is easy to cache but.. I rather only get data for just one page.
How would I only get data for the current page with my optional parameters? I have used stored procedures for this before but I don't think it's possible with PagedList.
How can I have cleaner code for optional parameters in my LINQ query? I don't like all those if statements..
The thing is you have to Skip items and then Take(pageSize)
var pagedNews = DB.News.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
So let's say you have 5 items / page.
If you are on page 1
(1 - 1) * 5 = 0 so skip zero Items and take 5
If you are on page 2
(2 - 1) * 5 = 5 so skip 5 Items and take 5
Your parameters are Nullable so you might have to put a default condition on your parameters say if NULL then PageSize = 5 and PageNumber = 1
int pageSize, int? newsID, int? page
EDIT:
Instead of:
if (cacheNews == null)
{
news = (from n in DB.News
select n).ToList();
...........
}
Use this:
// You will have to OrderBy() before doing the pagination:
// Read as Queryable()
var pagedNews = DB.News.AsQueryable();
// Apply OrderBy Logic
pagedNews = pagedNews.OrderBy();
//ApplyPagination
pagedNews = pagedNews.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
ORDER BY
You don't need to pass the OrderBy columns as separate strings.
Pass one string e.g. selectedSortBy from View,
I have created a Helper method:
using System;
using System.Linq;
using System.Linq.Expressions;
namespace Common.Helpers
{
public static class PaginationHelper
{
public static IQueryable<T> ApplyPagination<T>(IQueryable<T> source, Pagination pagination)
{
var sortDirection = pagination.SortDirection == SortDirectionEnum.Ascending ? "OrderBy" : "OrderByDescending";
var orderBy = pagination.SortBy ?? pagination.DefaultSortBy;
return source.OrderBy(orderBy, sortDirection).Skip((pagination.PageNumber - 1) * pagination.PageSize).Take(pagination.PageSize);
}
public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string ordering, string sortDirection, params object[] values)
{
var type = typeof(T);
var property = type.GetProperty(ordering);
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExp = Expression.Lambda(propertyAccess, parameter);
var resultExp = Expression.Call(typeof(Queryable), sortDirection, new Type[] { type, property.PropertyType }, source.Expression, Expression.Quote(orderByExp));
return source.Provider.CreateQuery<T>(resultExp);
}
}
}
Pagination Model + Enum:
namespace Common.Helpers
{
public class Pagination
{
public SortDirectionEnum SortDirection { get; set; }
public string SortBy { get; set; }
public int TotalRecords { get; set; }
public int NumberOfPages { get; set; }
public int PageSize { get; set; }
public int PageNumber { get; set; }
public string DefaultSortBy { get; set; }
public string ReloadUrl { get; set; }
public string TargetDiv { get; set; }
public Pagination()
{
}
public Pagination(string reloadUrl, string targetDiv, int totalRecords, int numberOfPages)
{
ReloadUrl = reloadUrl;
TargetDiv = targetDiv;
PageSize = 10;
PageNumber = 1;
}
}
public enum SortDirectionEnum
{
Ascending = 1,
Descending = 2
}
}
Then call your Query like this:
var items = DB.News.AsQueryable();
items = PaginationHelper.ApplyPagination(items, PAGINATION_MODEL);

How do I create a dynamic Linq query to fill an ASP.NET databound ListView?

I am having some trouble figuring out the right way to go about creating a dynamic query that I can use values from DropDownList controls to filter and sort/order the results of a database query to fill a ListView. I am able to hard code individual queries, which works ok, except for the fact that it takes an incredible amount of effort, and is not easily changed.
My code is as follows (using all filters):
queryResult = From product In myEntities.InventoryProducts
Where product.VendorID = ddlFilterVendor.SelectedValue And product.ItemType = ddlItemType.SelectedValue And product.LabelSize = ddlLabelSize.SelectedValue And product.PrintLabel = boolPrint And product.Edited = boolEdited
Order By product.ID Ascending
Select product
Return queryResult
Is there a better method to this? I would like to be able to select the value from each DropDownList and generate a custom WHERE clause, as well as an ORDER BY clause.
Any help would be greatly appreciated, thanks.
I can give you a simple example as to how to to proceed with your idea. I am sure if you look through StackOverflow or search via google you will get code that does a better job of dynamic expression building. The same concept can be used for order by.
void Main()
{
var ops = new List<Ops>
{
new Ops
{
OperandType = typeof(string),
OpType=OpType.Equals,
OperandName = "Name",
ValueToCompare = "MM" // in your case this will be the values from the dropdowns
},
new Ops
{
OperandType = typeof(int),
OpType=OpType.Equals,
OperandName = "ID",
ValueToCompare = 1
},
};
var testClasses = new List<TestClass>
{
new TestClass { ID =1, Name = "MM", Date = new DateTime(2014,12,1)},
new TestClass { ID =2, Name = "BB", Date = new DateTime(2014,12,2)}
};
// this will produce prop => ((prop.Name == "MM") And (prop.ID == 1))
var whereDelegate = ExpressionBuilder.BuildExpressions<TestClass>(ops);
foreach(var item in testClasses.Where(whereDelegate))
{
Console.WriteLine("ID " +item.ID);
Console.WriteLine("Name " +item.Name);
Console.WriteLine("Date" + item.Date);
}
}
// Define other methods and classes here
public enum OpType
{
Equals
}
public class Ops
{
public Type OperandType {get; set;}
public OpType OpType {get; set;}
public string OperandName {get;set;}
public object ValueToCompare {get;set;}
}
public class TestClass
{
public int ID {get;set;}
public string Name {get; set;}
public DateTime Date {get;set;}
}
public class ExpressionBuilder
{
public static Func<T,bool> BuildExpressions<T>( List<Ops> opList)
{
Expression currentExpression= null;
var parameterExpression = Expression.Parameter(typeof(T), "prop");
for(int i =0; i< opList.Count; i++)
{
var op = opList[i];
Expression innerExpression = null;
switch(op.OpType)
{
case OpType.Equals :
{
var propertyExpression = Expression.Property(parameterExpression ,
op.OperandName);
var constExpression = Expression.Constant(op.ValueToCompare);
innerExpression = Expression.Equal(propertyExpression,
constExpression);
break;
}
}
if (i >0)
{
currentExpression = Expression.And(currentExpression, innerExpression);
}
else
{
currentExpression = innerExpression;
}
}
var lambdaExpression = Expression.Lambda<Func<T,bool>>(currentExpression,
new []{parameterExpression });
Console.WriteLine(lambdaExpression);
return lambdaExpression.Compile() ;
}
}

why is my query not returning 6 items?

Afternoon,
Can any one see why my query is not returning a random 6 items please?
public class GetQuestions
{
public int qId { get; set; }
public string question { get; set; }
public string answer1 { get; set; }
public string answer2 { get; set; }
public string answer3 { get; set; }
}
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public List<GetQuestions> Questions()
{
using (QuizDataContext dc = new QuizDataContext())
{
var query = from q in dc.tblquizs
orderby Guid.NewGuid()
select new GetQuestions
{
qId = q.id,
question = q.q,
answer1 = q.a1,
answer2 = q.a2,
answer3 = q.a3,
};
return query.Take(6).ToList();
}
Updated Add the GetQuestions Class
You can't get random order by using
orderby Guid.NewGuid()
You can test this by doing the following query and seeing the result:
from q in dc.tblquizs
select Guid.NewGuid()
Entity Framework 4.3.1 will translate the Guid.NewGuid() call to newid() - this would definitely be the preferred methodology if your DAL supports it. It may be, however, that whatever DAL you're using doesn't translate the call properly (in which case it may get translated to a GUID before it's sent to the database server, resulting in a static value for ordering). You should use a database profiler to see what your DAL is doing.
If the Guid.NewGuid call is not translating to newid() properly, you have two other options:
Use a sproc
Use something like the LINQ below (as a last resort)
var context = new ScratchContext();
var products = new List<Product>();
for (int i = 0; i < num; i++)
{
Product product = null;
while (product == null)
{
int randomId = r.Next(context.Products.Count());
product = context.Products.FirstOrDefault(p => p.ID == randomId);
}
products.Add(product);
}
return products.AsQueryable();
I used the following code to resolve this issue.
var qry = from q in dc.tblwhiskysprintquizs.AsEnumerable()
orderby Guid.NewGuid()
select new GetQuestions
{
qId = q.id,
question = q.q,
answer1 = q.a1,
answer2 = q.a2,
answer3 = q.a3,
};
return qry.Take(6).ToList();
It was as simple as adding .AsEnumerable to the look up.
orderby Guid.NewGuid()
generates random numbers that may not exist in your db

Sorting IQueryable date column by string value in LINQ

I am trying to sort an IQueryable object by a specific column via a string input.
Calling .ToList() on the IQueryable and sorting via a list column works perfectly, however when sorting a date column, it sorts alphabetically, which is not ideal.
If anybody could point me in the correct direction here, I'd appreciate it.
My Usage
IQueryable<MyItemType> list = (from t1 in db.MyTable
select t1);
List<MyItemType> itemsSorted; // Sort here
if (!String.IsNullOrEmpty(OrderBy))
{
itemsSorted = list.OrderBy(OrderBy).ToList();
}
else
{
itemsSorted = list.ToList();
}
Extension Method
using System.Linq;
using System.Collections.Generic;
using System;
using System.Linq.Expressions;
using System.Reflection;
public static class OrderByHelper
{
public static IEnumerable<T> OrderBy<T>(this IEnumerable<T> enumerable, string orderBy)
{
return enumerable.AsQueryable().OrderBy(orderBy).AsEnumerable();
}
public static IQueryable<T> OrderBy<T>(this IQueryable<T> collection, string orderBy)
{
foreach (OrderByInfo orderByInfo in ParseOrderBy(orderBy))
collection = ApplyOrderBy<T>(collection, orderByInfo);
return collection;
}
private static IQueryable<T> ApplyOrderBy<T>(IQueryable<T> collection, OrderByInfo orderByInfo)
{
string[] props = orderByInfo.PropertyName.Split('.');
Type type = typeof(T);
ParameterExpression arg = Expression.Parameter(type, "x");
Expression expr = arg;
foreach (string prop in props)
{
// use reflection (not ComponentModel) to mirror LINQ
PropertyInfo pi = type.GetProperty(prop);
expr = Expression.Property(expr, pi);
type = pi.PropertyType;
}
Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T), type);
LambdaExpression lambda = Expression.Lambda(delegateType, expr, arg);
string methodName = String.Empty;
if (!orderByInfo.Initial && collection is IOrderedQueryable<T>)
{
if (orderByInfo.Direction == SortDirection.Ascending)
methodName = "ThenBy";
else
methodName = "ThenByDescending";
}
else
{
if (orderByInfo.Direction == SortDirection.Ascending)
methodName = "OrderBy";
else
methodName = "OrderByDescending";
}
//TODO: apply caching to the generic methodsinfos?
return (IOrderedQueryable<T>)typeof(Queryable).GetMethods().Single(
method => method.Name == methodName
&& method.IsGenericMethodDefinition
&& method.GetGenericArguments().Length == 2
&& method.GetParameters().Length == 2)
.MakeGenericMethod(typeof(T), type)
.Invoke(null, new object[] { collection, lambda });
}
private static IEnumerable<OrderByInfo> ParseOrderBy(string orderBy)
{
if (String.IsNullOrEmpty(orderBy))
yield break;
string[] items = orderBy.Split(',');
bool initial = true;
foreach (string item in items)
{
string[] pair = item.Trim().Split(' ');
if (pair.Length > 2)
throw new ArgumentException(String.Format("Invalid OrderBy string '{0}'. Order By Format: Property, Property2 ASC, Property2 DESC", item));
string prop = pair[0].Trim();
if (String.IsNullOrEmpty(prop))
throw new ArgumentException("Invalid Property. Order By Format: Property, Property2 ASC, Property2 DESC");
SortDirection dir = SortDirection.Ascending;
if (pair.Length == 2)
dir = ("desc".Equals(pair[1].Trim(), StringComparison.OrdinalIgnoreCase) ? SortDirection.Descending : SortDirection.Ascending);
yield return new OrderByInfo() { PropertyName = prop, Direction = dir, Initial = initial };
initial = false;
}
}
private class OrderByInfo
{
public string PropertyName { get; set; }
public SortDirection Direction { get; set; }
public bool Initial { get; set; }
}
private enum SortDirection
{
Ascending = 0,
Descending = 1
}
public static IQueryable<T> OrderByIQueryableStringValue<T>(this IQueryable<T> source, string ordering, params object[] values)
{
var type = typeof(T);
var property = type.GetProperty(ordering);
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExp = Expression.Lambda(propertyAccess, parameter);
MethodCallExpression resultExp = Expression.Call(typeof(Queryable), "OrderBy", new Type[] { type, property.PropertyType }, source.Expression, Expression.Quote(orderByExp));
return source.Provider.CreateQuery<T>(resultExp);
}
}
If you want there is already a library for dynamic linq that has a order by extension method (and others linq methods) that accepts string input for all the data types. See http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

Resources