使用 ODS、BusinessLayer 和 Dynamic Linq 的 ListView 无法排序
症状:ListView 不排序
数据层: Linq 生成的类,包括 Northwind Employee 表和 System.Linq.Dynamic 类
业务层:
namespace BusinessLayer
{
[Serializable]
public class EmployeeData
{
public int EmployeeId { get; set; }
public int? ReportsToId { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public string Title { get; set; }
public DateTime? BirthDate { get; set; }
public DateTime? HireDate { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }
}
[Serializable]
public class EmployeeFilter
{
public string LastName { get; set; }
public string FirstName { get; set; }
public string City { get; set; }
}
[Serializable]
public class EmployeeList
{
public int ListCount(EmployeeFilter filter, string sortType, int startRowIndex, int maximumRows)
{
var rows = listQuery();
return rows.Count();
}
public IEnumerable<EmployeeData> List(EmployeeFilter filter, string sortType, int startRowIndex, int maximumRows)
{
var rows = listQuery();
if (!string.IsNullOrEmpty(sortType)) rows = listSort(rows, sortType);
return (maximumRows > 0)
? rows.Distinct().Skip(startRowIndex).Take(maximumRows).ToList()
: rows.Distinct().Skip(startRowIndex).ToList();
}
public IQueryable<EmployeeData> listQuery()
{
var dc = new NorthwindDataContext();
var allrows = from emp in dc.Employees
select new EmployeeData()
{
EmployeeId = emp.EmployeeID,
ReportsToId = emp.ReportsTo,
FirstName = emp.FirstName,
LastName = emp.LastName,
Address = emp.Address,
City = emp.City,
PostalCode = emp.PostalCode,
BirthDate = emp.BirthDate,
HireDate = emp.HireDate,
Title = emp.Title,
};
return allrows;
}
public IQueryable<EmployeeData> listSort(IQueryable<EmployeeData> rows, string sortType)
{
bool sortDescending = false;
if (!string.IsNullOrEmpty(sortType))
{
string[] values = sortType.Split(' ');
sortType = values[0];
if (values.Length > 1)
{
sortDescending = (values[1] == "DESC");
}
}
if (!string.IsNullOrEmpty(sortType))
{
rows = rows.OrderBy(string.Format("{0}{1}",sortType,(sortDescending) ? " DESC" : ""));
}
return rows;
}
}
}
用户层:
<asp:ListView ID="lstEmployees" runat="server" DataSourceID="odsEmployees" >
<LayoutTemplate>
<table>
<tr>
<th align="left">
<asp:LinkButton runat="server" ID="LinkButton1" CommandName="Sort" CommandArgument="FirstName">First Name</asp:LinkButton>
</th>
<th align="left">
<asp:LinkButton runat="server" ID="LinkButton5" CommandName="Sort" CommandArgument="LastName">Last Name</asp:LinkButton>
</th>
<th align="left">
<asp:LinkButton runat="server" ID="LinkButton6" CommandName="Sort" CommandArgument="BirthDate">Birth Date</asp:LinkButton>
</th>
</tr>
<asp:PlaceHolder ID="itemPlaceholder" runat="server"></asp:PlaceHolder>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><%#Eval("FirstName") %></td>
<td><%#Eval("LastName") %></td>
<td><%#string.Format("{0:d}", Eval("BirthDate"))%></td>
</tr>
</ItemTemplate>
<EmptyDataTemplate>
Sorry - no employees found
</EmptyDataTemplate>
</asp:ListView>
<asp:ObjectDataSource ID="odsEmployees" runat="server" EnablePaging="True" OldValuesParameterFormatString="original_{0}"
SelectCountMethod="ListCount" SelectMethod="List" SortParameterName="sortType"
TypeName="BusinessLayer.EmployeeList">
<SelectParameters>
<asp:SessionParameter Name="filter" SessionField="employeeFilter" Type="Object" />
<asp:Parameter Name="sortType" Type="String" />
<asp:Parameter Name="startRowIndex" Type="Int32" />
<asp:Parameter Name="maximumRows" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
分析: 我对此进行了详尽的测试。正在调用排序代码,并且从 List 方法返回的查询已正确排序;但是,表单上显示的数据未排序。
listSort 返回此 SQL 查询:
SELECT [t0].[EmployeeID] AS [EmployeeId], [t0].[ReportsTo] AS [ReportsToId], [t0].[LastName], [t0].[FirstName], [t0].[Title], [t0].[BirthDate], [t0].[HireDate], [t0].[Address], [t0].[City], [t0].[PostalCode]
FROM [dbo].[Employees] AS [t0]
ORDER BY [t0].[BirthDate] DESC
进一步测试表明我使用 GridView 得到了相同的结果
Symptoms: ListView not sorting
Data Layer: Linq-generated class that includes Northwind Employee table and System.Linq.Dynamic class
Business Layer:
namespace BusinessLayer
{
[Serializable]
public class EmployeeData
{
public int EmployeeId { get; set; }
public int? ReportsToId { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public string Title { get; set; }
public DateTime? BirthDate { get; set; }
public DateTime? HireDate { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }
}
[Serializable]
public class EmployeeFilter
{
public string LastName { get; set; }
public string FirstName { get; set; }
public string City { get; set; }
}
[Serializable]
public class EmployeeList
{
public int ListCount(EmployeeFilter filter, string sortType, int startRowIndex, int maximumRows)
{
var rows = listQuery();
return rows.Count();
}
public IEnumerable<EmployeeData> List(EmployeeFilter filter, string sortType, int startRowIndex, int maximumRows)
{
var rows = listQuery();
if (!string.IsNullOrEmpty(sortType)) rows = listSort(rows, sortType);
return (maximumRows > 0)
? rows.Distinct().Skip(startRowIndex).Take(maximumRows).ToList()
: rows.Distinct().Skip(startRowIndex).ToList();
}
public IQueryable<EmployeeData> listQuery()
{
var dc = new NorthwindDataContext();
var allrows = from emp in dc.Employees
select new EmployeeData()
{
EmployeeId = emp.EmployeeID,
ReportsToId = emp.ReportsTo,
FirstName = emp.FirstName,
LastName = emp.LastName,
Address = emp.Address,
City = emp.City,
PostalCode = emp.PostalCode,
BirthDate = emp.BirthDate,
HireDate = emp.HireDate,
Title = emp.Title,
};
return allrows;
}
public IQueryable<EmployeeData> listSort(IQueryable<EmployeeData> rows, string sortType)
{
bool sortDescending = false;
if (!string.IsNullOrEmpty(sortType))
{
string[] values = sortType.Split(' ');
sortType = values[0];
if (values.Length > 1)
{
sortDescending = (values[1] == "DESC");
}
}
if (!string.IsNullOrEmpty(sortType))
{
rows = rows.OrderBy(string.Format("{0}{1}",sortType,(sortDescending) ? " DESC" : ""));
}
return rows;
}
}
}
User Layer:
<asp:ListView ID="lstEmployees" runat="server" DataSourceID="odsEmployees" >
<LayoutTemplate>
<table>
<tr>
<th align="left">
<asp:LinkButton runat="server" ID="LinkButton1" CommandName="Sort" CommandArgument="FirstName">First Name</asp:LinkButton>
</th>
<th align="left">
<asp:LinkButton runat="server" ID="LinkButton5" CommandName="Sort" CommandArgument="LastName">Last Name</asp:LinkButton>
</th>
<th align="left">
<asp:LinkButton runat="server" ID="LinkButton6" CommandName="Sort" CommandArgument="BirthDate">Birth Date</asp:LinkButton>
</th>
</tr>
<asp:PlaceHolder ID="itemPlaceholder" runat="server"></asp:PlaceHolder>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><%#Eval("FirstName") %></td>
<td><%#Eval("LastName") %></td>
<td><%#string.Format("{0:d}", Eval("BirthDate"))%></td>
</tr>
</ItemTemplate>
<EmptyDataTemplate>
Sorry - no employees found
</EmptyDataTemplate>
</asp:ListView>
<asp:ObjectDataSource ID="odsEmployees" runat="server" EnablePaging="True" OldValuesParameterFormatString="original_{0}"
SelectCountMethod="ListCount" SelectMethod="List" SortParameterName="sortType"
TypeName="BusinessLayer.EmployeeList">
<SelectParameters>
<asp:SessionParameter Name="filter" SessionField="employeeFilter" Type="Object" />
<asp:Parameter Name="sortType" Type="String" />
<asp:Parameter Name="startRowIndex" Type="Int32" />
<asp:Parameter Name="maximumRows" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
Analysis:
I have tested this exhaustively. The sort code is getting called and the query that gets returned from the List method is correctly sorted; however, the data displayed on the form is not sorted.
listSort is returning this SQL query:
SELECT [t0].[EmployeeID] AS [EmployeeId], [t0].[ReportsTo] AS [ReportsToId], [t0].[LastName], [t0].[FirstName], [t0].[Title], [t0].[BirthDate], [t0].[HireDate], [t0].[Address], [t0].[City], [t0].[PostalCode]
FROM [dbo].[Employees] AS [t0]
ORDER BY [t0].[BirthDate] DESC
Further testing reveals that I get the same results with a GridView
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
事实证明,对象数据源 (ODS) 不使用 IEnumerable 进行排序。 Linq 代码必须返回 DataTable 或 DataSet。我找到了两篇文章展示了如何做到这一点。其中一个已经接近但不完整。另一个像魔术一样起作用:
Linq To数据表。
这是我在短短几分钟内找到并成功运行的代码:
这是新的 List 方法:
Turns out that an Object Data Source (ODS) does not do sorting with an IEnumerable. The Linq code must return a DataTable or DataSet. I found two articles that showed how to do that. One was close but incomplete. The other worked like magic:
Linq To DataTable.
Here is the code that I found and managed to get working in just a few minutes:
And here is the new List method:
老实说,我不知道 ListView 如何或是否可以与 ODS 一起使用。我只将 ListViews 与 LDS 一起使用,但我确实看到了一个可能的代码问题。如果你期待其中一个或另一个开火,你就不会明白。
I honestly don't know how or if a ListView will work with an ODS. I have only used ListViews with an LDS but I do see one possible code issue. If you are expecting one or the other here to fire, you won't get that.