Entity framework 具有联接和条件OrderBy/OrderByDescending的Linq表达式
我正在构建一个Linq表达式,我没有能力在这个项目中使用动态Linq。这是我的初步声明Entity framework 具有联接和条件OrderBy/OrderByDescending的Linq表达式,entity-framework,linq,linq-to-sql,asp.net-mvc-5,Entity Framework,Linq,Linq To Sql,Asp.net Mvc 5,我正在构建一个Linq表达式,我没有能力在这个项目中使用动态Linq。这是我的初步声明 var orderListQuery = context.Orders.Where(oExpr) .Join(context.Members, o => o.MemberId, m => m.Id,
var orderListQuery = context.Orders.Where(oExpr)
.Join(context.Members,
o => o.MemberId,
m => m.Id,
(o, m) => new {Order = o, Member = m})
.Where(oM => oM.Member.CustomerId == custId);
下一部分是我想有条件地添加一个降序表达式:
orderListQuery = descending
? orderListQuery.OrderByDescending(sortProperty)
: orderListQuery.OrderBy(sortProperty);
我在文章中看到的错误是,我需要显式列出
,但由于连接语法的复杂性,我不知道如何显式列出这些。我尝试了
,但不起作用
任何有帮助的,谢谢。因为你忘了写下你想要达到的目标(没有具体说明),所以有点不清楚你的问题是什么,以及如何解决。我假设您的问题不是连接(尽管可以简化),而是方法的用户如何提供排序属性 如何指定和使用排序属性 问题是,函数的调用方决定排序属性。当然,您只想创建有用且可重用的函数,因此您不想限制函数的用户,他可以指定他想要的任何排序属性,只要它是可以对联接结果进行排序的属性 联接的结果包含来自
订单序列
和成员序列
的数据。很明显,您的用户只能请求根据订单
和/或成员
中的值(组合)对您的加入结果进行排序
Queryable.OrderBy
中的键选择器的格式为Expression keySelector
。在这种格式中,TSource是您加入的结果
由于用户只能对订单
和/或成员
中的值进行排序,因此他的键选择器应该是从订单
和/或成员
中选择键的功能
public MyResult MyQuery<TKey>(Expression<Func<Order, Member, TKey> keySelector,
SortOrder sortOrder)
{
... // TODO: your query?
}
现在指定了接口,让我们定义一些帮助器类并填充函数
class MyResult
{
public Order Order {get; set;}
public Member Member {get; set;}
}
class SortableMyResult<TKey>
{
public TKey SortKey {get; set;}
public MyResult MyResult {get; set;}
}
MyResult MyQuery<TKey>(
Expression<Func<Order, Member, TKey> keySelector, SortOrder sortOrder)
{
var query = context.Orders.Where(oExpr)
.Join(context.Members,
order => order.MemberId,
member => member.Id,
(order, member) => new SortableMyResult<TKey>()
{
SortKey = KeySelector(order, member),
MyResult = new MyResult()
{
Order = order,
Member = member,
}
))
.Where(....);
最后,提取并返回MyResult:
return sortedMyResult.Select(sortedMyResult => sortedMyResult.MyResult);
如果您想使您的函数更通用,可以让调用者提供一个i比较程序
(如果他不提供,则使用TKey的默认比较程序
):
MyResult MyQuery(
Expression感谢您提供了令人难以置信的详细答案。几个月过去了,关于MVC和现有应用程序代码的更多信息变得清晰起来。在我的例子中,我们定义了一个扩展方法,允许OrderBy和OrderByDescending接受排序模块从前端传入的字符串。e。g:
public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> source, string propertyName)
{
return GetExpression(source, propertyName);
}
公共静态IOrderedQueryable OrderByDescending(此IQueryable源,字符串propertyName)
{
返回GetExpression(源,propertyName);
}
然后将其导入一个GetExpression函数,该函数返回一个IOrderedQueryable
我没有提到这一点,由于我对框架和应用程序都缺乏经验,所以我毫无理由地绞尽脑汁。你需要构造一个指向你的属性的表达式。但是如果你只描述一下你试图用这段代码实现什么,那会更好,因为有pr可能更容易做到这一点:成员Id与客户Id不同,客户Id不在订单上。但是,成员Id和客户Id是成员表的一部分。(遗留代码问题)我正在尝试按客户Id获取所有订单,并根据视图中作为操作请求发送的sortProperty对其进行排序。(例如,按日期排序、小计等)。在这种情况下,sortProperty始终是一个字符串。因此,sortProperty
是一个包含属性名的字符串?@MichaelSefranek所以为什么不设置外键,然后正常地获取数据呢?从链接中获取类,然后使用.OrderByMember(“Order.+sortProperty”)
。类似于降序。
return sortedMyResult.Select(sortedMyResult => sortedMyResult.MyResult);
MyResult MyQuery<TKey>(
Expression<Func<Order, Member, TKey> keySelector,
SortOrder sortOrder,
IComparer<TKey> comparer = EqualityComparer<TKey>.Default)
{
...
}
public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> source, string propertyName)
{
return GetExpression(source, propertyName);
}