Linq to SQL OrderBy 基于 DropDownList 中的选定值
Linq to SQL OrderBy based on selectedvalue from DropDownList
我有一个包含 10 篇文章的列表,这些文章在页面加载事件中通过以下 Linq to SQL 查询显示:
if (!Page.IsPostBack)
{
MyDataClassesDataContext db = new MyDataClassesDataContext();
var pressRelease = from pr in db.PressReleases
orderby pr.DatePublished ascending
where pr.Published == true
select pr;
int i = 0;
foreach (var release in pressRelease)
{
Literal literal = new Literal();
literal.Text = "<div class='row no-gutters pb-5'><div class='col-12'><h2>" +
release.Title + "</h2>" + Server.HtmlDecode(release.Content) + "</h2>" +
"<a href='Press-Release.aspx?id=" + release.Id +
"'><b>Read article...</b></a></div></div>";
pnlPressReleaases.Controls.Add(literal);
}
}
在我的网页上,我有一个包含以下值的下拉列表,并且自动回传设置为 true。
<asp:DropDownList ID="ddlPressSortBy" AutoPostBack="True" runat="server" OnSelectedIndexChanged="ddlPressSortBy_SelectedIndexChanged">
<asp:ListItem Value="pr.DatePublished descending">Date Published Desc</asp:ListItem>
<asp:ListItem Selected="True" Value="pr.DatePublished ascending">Date Published Asc</asp:ListItem>
<asp:ListItem Value="pr.Title ascending">Alphabetical</asp:ListItem>
</asp:DropDownList>
一旦我更改下拉列表的值,返回的数据在相应的select 语句上没有orderby。这是我的 OnSelectIndexChanged 事件代码:
protected void ddlPressSortBy_SelectedIndexChanged(object sender, EventArgs e)
{
MyDataClassesDataContext db = new MyDataClassesDataContext();
var pressRelease = from pr in db.PressReleases
orderby ddlPressSortBy.SelectedValue
where pr.Published == true
select pr;
foreach (var release in pressRelease)
{
Literal literal = new Literal();
literal.Text = "<div class='row no-gutters pb-5'><div class='col-12'><h2>" +
release.Title + "</h2>" + Server.HtmlDecode(release.Content) + "</h2>" + "<a href='Press-Release.aspx?id=" + release.Id + "'><b>Read article...</b></a></div></div>";
pnlPressReleaases.Controls.Add(literal);
}
}
我有点不确定为什么它没有用 orderby 触发。
如有任何帮助,我们将不胜感激。
谢谢
罗布
你不能这样排序:
var pressRelease = from pr in db.PressReleases
orderby ddlPressSortBy.SelectedValue
where pr.Published == true
select pr;
因为生成的查询类似于(假设您选择了第一项):
SELECT * FROM PressReleases
WHERE Published = 1
ORDER BY 'pr.DatePublished descending'
ORDER BY
子句将按固定值排序,从而导致默认排序。
Linq OrderBy 采用 Expression<Func<T, object>>
,如果您使用的是 Fluent 语法,则类似于 pr => pr.DatePublishing
。查询语法只是以漂亮的形式隐藏了它,但它是如何工作的。
根据 this article,您可以为 IQueryable 创建一个扩展方法,允许您使用 属性 个名称进行排序:
public static class extensionmethods
{
public static IQueryable<T> OrderByField<T>(this IQueryable<T> q, string SortField, bool Ascending)
{
var param = Expression.Parameter(typeof(T), "p");
var prop = Expression.Property(param, SortField);
var exp = Expression.Lambda(prop, param);
string method = Ascending ? "OrderBy" : "OrderByDescending";
Type[] types = new Type[] { q.ElementType, exp.Body.Type };
var mce = Expression.Call(typeof(Queryable), method, types, q.Expression, exp);
return q.Provider.CreateQuery<T>(mce);
}
}
然后像这样在您的代码中使用它:
var sortingInfo = ddlPressSortBy.SelectedValue.Split(' ');
var sortingProperty = sortingInfo[0];
var descending = sortingInfo[1] == "descending";
var pressRelease = from pr in db.PressReleases
where pr.Published == true
select pr;
pressRelease = pressRelease.OrderByField(sortingProperty, descending);
// rest of code
我有一个包含 10 篇文章的列表,这些文章在页面加载事件中通过以下 Linq to SQL 查询显示:
if (!Page.IsPostBack)
{
MyDataClassesDataContext db = new MyDataClassesDataContext();
var pressRelease = from pr in db.PressReleases
orderby pr.DatePublished ascending
where pr.Published == true
select pr;
int i = 0;
foreach (var release in pressRelease)
{
Literal literal = new Literal();
literal.Text = "<div class='row no-gutters pb-5'><div class='col-12'><h2>" +
release.Title + "</h2>" + Server.HtmlDecode(release.Content) + "</h2>" +
"<a href='Press-Release.aspx?id=" + release.Id +
"'><b>Read article...</b></a></div></div>";
pnlPressReleaases.Controls.Add(literal);
}
}
在我的网页上,我有一个包含以下值的下拉列表,并且自动回传设置为 true。
<asp:DropDownList ID="ddlPressSortBy" AutoPostBack="True" runat="server" OnSelectedIndexChanged="ddlPressSortBy_SelectedIndexChanged">
<asp:ListItem Value="pr.DatePublished descending">Date Published Desc</asp:ListItem>
<asp:ListItem Selected="True" Value="pr.DatePublished ascending">Date Published Asc</asp:ListItem>
<asp:ListItem Value="pr.Title ascending">Alphabetical</asp:ListItem>
</asp:DropDownList>
一旦我更改下拉列表的值,返回的数据在相应的select 语句上没有orderby。这是我的 OnSelectIndexChanged 事件代码:
protected void ddlPressSortBy_SelectedIndexChanged(object sender, EventArgs e)
{
MyDataClassesDataContext db = new MyDataClassesDataContext();
var pressRelease = from pr in db.PressReleases
orderby ddlPressSortBy.SelectedValue
where pr.Published == true
select pr;
foreach (var release in pressRelease)
{
Literal literal = new Literal();
literal.Text = "<div class='row no-gutters pb-5'><div class='col-12'><h2>" +
release.Title + "</h2>" + Server.HtmlDecode(release.Content) + "</h2>" + "<a href='Press-Release.aspx?id=" + release.Id + "'><b>Read article...</b></a></div></div>";
pnlPressReleaases.Controls.Add(literal);
}
}
我有点不确定为什么它没有用 orderby 触发。
如有任何帮助,我们将不胜感激。
谢谢 罗布
你不能这样排序:
var pressRelease = from pr in db.PressReleases
orderby ddlPressSortBy.SelectedValue
where pr.Published == true
select pr;
因为生成的查询类似于(假设您选择了第一项):
SELECT * FROM PressReleases
WHERE Published = 1
ORDER BY 'pr.DatePublished descending'
ORDER BY
子句将按固定值排序,从而导致默认排序。
Linq OrderBy 采用 Expression<Func<T, object>>
,如果您使用的是 Fluent 语法,则类似于 pr => pr.DatePublishing
。查询语法只是以漂亮的形式隐藏了它,但它是如何工作的。
根据 this article,您可以为 IQueryable 创建一个扩展方法,允许您使用 属性 个名称进行排序:
public static class extensionmethods
{
public static IQueryable<T> OrderByField<T>(this IQueryable<T> q, string SortField, bool Ascending)
{
var param = Expression.Parameter(typeof(T), "p");
var prop = Expression.Property(param, SortField);
var exp = Expression.Lambda(prop, param);
string method = Ascending ? "OrderBy" : "OrderByDescending";
Type[] types = new Type[] { q.ElementType, exp.Body.Type };
var mce = Expression.Call(typeof(Queryable), method, types, q.Expression, exp);
return q.Provider.CreateQuery<T>(mce);
}
}
然后像这样在您的代码中使用它:
var sortingInfo = ddlPressSortBy.SelectedValue.Split(' ');
var sortingProperty = sortingInfo[0];
var descending = sortingInfo[1] == "descending";
var pressRelease = from pr in db.PressReleases
where pr.Published == true
select pr;
pressRelease = pressRelease.OrderByField(sortingProperty, descending);
// rest of code