ExtJs+WCF+LINQ实现分页Grid
上篇文章《用ExtJs+Linq+Wcf打造简单grid 》,这个网格控件不带分页,本文在上文的基础上添加分页功能,文中会着重介绍如何在用LINQ返回分页数据,如何使ExtJs与WCF进行Restful交互,如何在页面中添加一个带有分页功能的ExtJS的Grid控件。
废话也不多说了,本文仍然是实战学习系列,没有太多理论讲解,只是作者学习中的操作流程记录而已,如果日后有机会,会逐渐的深入一些。
第一步:在vs2008中创建一个支持.Net Framework 3.5,名称为:ExtJs_Wcf_Linq_PageGrid的Asp.Net网站,
完成后删除项目模板中的default.aspx页面。此步骤完成之后的效果图如下:
第二步:创建网站之后,将ExtJs相关资源文件添加到项目中,这些文件主要来源是extjs的官方示例项目,完成后项目效果图为:
第三步:在本文的示例中,我们使用SQL2005自带的示例数据库AdventureWorks中的数据表Product,默认情况下该示例数据库可能未安装,要安装此数据库,可以查阅SQL2005中文档与教程中的SQL2005联机文档。在这个步骤中,主要目的是在项目创建一个Lint to Xml类,这个类用于Linq与数据表Product进行交互。使用Linq To Sql可以产生一个实体类和一个数据访问类。添加该类的操作如下:
创建好Products.dbml之后,打开vs2008的服务器资源管理器,在服务器资源管理器中添加对数据库AdventureWorks的数据连接,然后将该库中数据表Product拖到Products.dbml设计器的左面的对象关系设计器面板中,操作如下图所示:
、
拖动成功之后,便有vs2008的IDE自动生成了有关Product的实体类和linq操作数据表Product的操作类:ProductsDataContext,在可视化界面中也能有如下的显示:
自动生成的实体类Product并不支持作为WCF的数据类,必须手动对其添加DataContract和DataMember,添加后的代码如下:
#pragma warning disable 1591
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行库版本:2.0.50727.1433
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace ExtJs_Wcf_Linq_PageGrid
{
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Data;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using System.Linq.Expressions;
using System.ComponentModel;
using System;
using System.Runtime.Serialization;
[System.Data.Linq.Mapping.DatabaseAttribute(Name="AdventureWorks")]
public partial class ProductsDataContext : System.Data.Linq.DataContext
{
private static System.Data.Linq.Mapping.MappingSource mappingSource = new AttributeMappingSource();
Extensibility Method Definitions#region Extensibility Method Definitions
partial void OnCreated();
partial void InsertProduct(Product instance);
partial void UpdateProduct(Product instance);
partial void DeleteProduct(Product instance);
#endregion
public ProductsDataContext() :
base(global::System.Configuration.ConfigurationManager.ConnectionStrings["AdventureWorksConnectionString"].ConnectionString, mappingSource)
{
OnCreated();
}
public ProductsDataContext(string connection) :
base(connection, mappingSource)
{
OnCreated();
}
public ProductsDataContext(System.Data.IDbConnection connection) :
base(connection, mappingSource)
{
OnCreated();
}
public ProductsDataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
base(connection, mappingSource)
{
OnCreated();
}
public ProductsDataContext(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
base(connection, mappingSource)
{
OnCreated();
}
public System.Data.Linq.Table<Product> Product
{
get
{
return this.GetTable<Product>();
}
}
}
[Table(Name="Production.Product")]
[DataContract]
public partial class Product : INotifyPropertyChanging, INotifyPropertyChanged
{
private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
private int _ProductID;
private string _Name;
private string _ProductNumber;
private bool _MakeFlag;
private bool _FinishedGoodsFlag;
private string _Color;
private short _SafetyStockLevel;
private short _ReorderPoint;
private decimal _StandardCost;
private decimal _ListPrice;
private string _Size;
private string _SizeUnitMeasureCode;
private string _WeightUnitMeasureCode;
private System.Nullable<decimal> _Weight;
private int _DaysToManufacture;
private string _ProductLine;
private string _Class;
private string _Style;
private System.Nullable<int> _ProductSubcategoryID;
private System.Nullable<int> _ProductModelID;
private System.DateTime _SellStartDate;
private System.Nullable<System.DateTime> _SellEndDate;
private System.Nullable<System.DateTime> _DiscontinuedDate;
private System.Guid _rowguid;
private System.DateTime _ModifiedDate;
Extensibility Method Definitions#region Extensibility Method Definitions
partial void OnLoaded();
partial void OnValidate(System.Data.Linq.ChangeAction action);
partial void OnCreated();
partial void OnProductIDChanging(int value);
partial void OnProductIDChanged();
partial void OnNameChanging(string value);
partial void OnNameChanged();
partial void OnProductNumberChanging(string value);
partial void OnProductNumberChanged();
partial void OnMakeFlagChanging(bool value);
partial void OnMakeFlagChanged();
partial void OnFinishedGoodsFlagChanging(bool value);
partial void OnFinishedGoodsFlagChanged();
partial void OnColorChanging(string value);
partial void OnColorChanged();
partial void OnSafetyStockLevelChanging(short value);
partial void OnSafetyStockLevelChanged();
partial void OnReorderPointChanging(short value);
partial void OnReorderPointChanged();
partial void OnStandardCostChanging(decimal value);
partial void OnStandardCostChanged();
partial void OnListPriceChanging(decimal value);
partial void OnListPriceChanged();
partial void OnSizeChanging(string value);
partial void OnSizeChanged();
partial void OnSizeUnitMeasureCodeChanging(string value);
partial void OnSizeUnitMeasureCodeChanged();
partial void OnWeightUnitMeasureCodeChanging(string value);
partial void OnWeightUnitMeasureCodeChanged();
partial void OnWeightChanging(System.Nullable<decimal> value);
partial void OnWeightChanged();
partial void OnDaysToManufactureChanging(int value);
partial void OnDaysToManufactureChanged();
partial void OnProductLineChanging(string value);
partial void OnProductLineChanged();
partial void OnClassChanging(string value);
partial void OnClassChanged();
partial void OnStyleChanging(string value);
partial void OnStyleChanged();
partial void OnProductSubcategoryIDChanging(System.Nullable<int> value);
partial void OnProductSubcategoryIDChanged();
partial void OnProductModelIDChanging(System.Nullable<int> value);
partial void OnProductModelIDChanged();
partial void OnSellStartDateChanging(System.DateTime value);
partial void OnSellStartDateChanged();
partial void OnSellEndDateChanging(System.Nullable<System.DateTime> value);
partial void OnSellEndDateChanged();
partial void OnDiscontinuedDateChanging(System.Nullable<System.DateTime> value);
partial void OnDiscontinuedDateChanged();
partial void OnrowguidChanging(System.Guid value);
partial void OnrowguidChanged();
partial void OnModifiedDateChanging(System.DateTime value);
partial void OnModifiedDateChanged();
#endregion
public Product()
{
OnCreated();
}
[DataMember]
[Column(Storage="_ProductID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
public int ProductID
{
get
{
return this._ProductID;
}
set
{
if ((this._ProductID != value))
{
this.OnProductIDChanging(value);
this.SendPropertyChanging();
this._ProductID = value;
this.SendPropertyChanged("ProductID");
this.OnProductIDChanged();
}
}
}
[DataMember]
[Column(Storage="_Name", DbType="NVarChar(50) NOT NULL", CanBeNull=false)]
public string Name
{
get
{
return this._Name;
}
set
{
if ((this._Name != value))
{
this.OnNameChanging(value);
this.SendPropertyChanging();
this._Name = value;
this.SendPropertyChanged("Name");
this.OnNameChanged();
}
}
}
[DataMember]
[Column(Storage="_ProductNumber", DbType="NVarChar(25) NOT NULL", CanBeNull=false)]
public string ProductNumber
{
get
{
return this._ProductNumber;
}
set
{
if ((this._ProductNumber != value))
{
this.OnProductNumberChanging(value);
this.SendPropertyChanging();
this._ProductNumber = value;
this.SendPropertyChanged("ProductNumber");
this.OnProductNumberChanged();
}
}
}
[DataMember]
[Column(Storage="_MakeFlag", DbType="Bit NOT NULL")]
public bool MakeFlag
{
get
{
return this._MakeFlag;
}
set
{
if ((this._MakeFlag != value))
{
this.OnMakeFlagChanging(value);
this.SendPropertyChanging();
this._MakeFlag = value;
this.SendPropertyChanged("MakeFlag");
this.OnMakeFlagChanged();
}
}
}
[DataMember]
[Column(Storage="_FinishedGoodsFlag", DbType="Bit NOT NULL")]
public bool FinishedGoodsFlag
{
get
{
return this._FinishedGoodsFlag;
}
set
{
if ((this._FinishedGoodsFlag != value))
{
this.OnFinishedGoodsFlagChanging(value);
this.SendPropertyChanging();
this._FinishedGoodsFlag = value;
this.SendPropertyChanged("FinishedGoodsFlag");
this.OnFinishedGoodsFlagChanged();
}
}
}
[DataMember]
[Column(Storage="_Color", DbType="NVarChar(15)")]
public string Color
{
get
{
return this._Color;
}
set
{
if ((this._Color != value))
{
this.OnColorChanging(value);
this.SendPropertyChanging();
this._Color = value;
this.SendPropertyChanged("Color");
this.OnColorChanged();
}
}
}
[DataMember]
[Column(Storage="_SafetyStockLevel", DbType="SmallInt NOT NULL")]
public short SafetyStockLevel
{
get
{
return this._SafetyStockLevel;
}
set
{
if ((this._SafetyStockLevel != value))
{
this.OnSafetyStockLevelChanging(value);
this.SendPropertyChanging();
this._SafetyStockLevel = value;
this.SendPropertyChanged("SafetyStockLevel");
this.OnSafetyStockLevelChanged();
}
}
}
[DataMember]
[Column(Storage="_ReorderPoint", DbType="SmallInt NOT NULL")]
public short ReorderPoint
{
get
{
return this._ReorderPoint;
}
set
{
if ((this._ReorderPoint != value))
{
this.OnReorderPointChanging(value);
this.SendPropertyChanging();
this._ReorderPoint = value;
this.SendPropertyChanged("ReorderPoint");
this.OnReorderPointChanged();
}
}
}
[DataMember]
[Column(Storage="_StandardCost", DbType="Money NOT NULL")]
public decimal StandardCost
{
get
{
return this._StandardCost;
}
set
{
if ((this._StandardCost != value))
{
this.OnStandardCostChanging(value);
this.SendPropertyChanging();
this._StandardCost = value;
this.SendPropertyChanged("StandardCost");
this.OnStandardCostChanged();
}
}
}
[DataMember]
[Column(Storage="_ListPrice", DbType="Money NOT NULL")]
public decimal ListPrice
{
get
{
return this._ListPrice;
}
set
{
if ((this._ListPrice != value))
{
this.OnListPriceChanging(value);
this.SendPropertyChanging();
this._ListPrice = value;
this.SendPropertyChanged("ListPrice");
this.OnListPriceChanged();
}
}
}
[DataMember]
[Column(Storage="_Size", DbType="NVarChar(5)")]
public string Size
{
get
{
return this._Size;
}
set
{
if ((this._Size != value))
{
this.OnSizeChanging(value);
this.SendPropertyChanging();
this._Size = value;
this.SendPropertyChanged("Size");
this.OnSizeChanged();
}
}
}
[DataMember]
[Column(Storage="_SizeUnitMeasureCode", DbType="NChar(3)")]
public string SizeUnitMeasureCode
{
get
{
return this._SizeUnitMeasureCode;
}
set
{
if ((this._SizeUnitMeasureCode != value))
{
this.OnSizeUnitMeasureCodeChanging(value);
this.SendPropertyChanging();
this._SizeUnitMeasureCode = value;
this.SendPropertyChanged("SizeUnitMeasureCode");
this.OnSizeUnitMeasureCodeChanged();
}
}
}
[DataMember]
[Column(Storage="_WeightUnitMeasureCode", DbType="NChar(3)")]
public string WeightUnitMeasureCode
{
get
{
return this._WeightUnitMeasureCode;
}
set
{
if ((this._WeightUnitMeasureCode != value))
{
this.OnWeightUnitMeasureCodeChanging(value);
this.SendPropertyChanging();
this._WeightUnitMeasureCode = value;
this.SendPropertyChanged("WeightUnitMeasureCode");
this.OnWeightUnitMeasureCodeChanged();
}
}
}
[DataMember]
[Column(Storage="_Weight", DbType="Decimal(8,2)")]
public System.Nullable<decimal> Weight
{
get
{
return this._Weight;
}
set
{
if ((this._Weight != value))
{
this.OnWeightChanging(value);
this.SendPropertyChanging();
this._Weight = value;
this.SendPropertyChanged("Weight");
this.OnWeightChanged();
}
}
}
[DataMember]
[Column(Storage="_DaysToManufacture", DbType="Int NOT NULL")]
public int DaysToManufacture
{
get
{
return this._DaysToManufacture;
}
set
{
if ((this._DaysToManufacture != value))
{
this.OnDaysToManufactureChanging(value);
this.SendPropertyChanging();
this._DaysToManufacture = value;
this.SendPropertyChanged("DaysToManufacture");
this.OnDaysToManufactureChanged();
}
}
}
[DataMember]
[Column(Storage="_ProductLine", DbType="NChar(2)")]
public string ProductLine
{
get
{
return this._ProductLine;
}
set
{
if ((this._ProductLine != value))
{
this.OnProductLineChanging(value);
this.SendPropertyChanging();
this._ProductLine = value;
this.SendPropertyChanged("ProductLine");
this.OnProductLineChanged();
}
}
}
[DataMember]
[Column(Storage="_Class", DbType="NChar(2)")]
public string Class
{
get
{
return this._Class;
}
set
{
if ((this._Class != value))
{
this.OnClassChanging(value);
this.SendPropertyChanging();
this._Class = value;
this.SendPropertyChanged("Class");
this.OnClassChanged();
}
}
}
[DataMember]
[Column(Storage="_Style", DbType="NChar(2)")]
public string Style
{
get
{
return this._Style;
}
set
{
if ((this._Style != value))
{
this.OnStyleChanging(value);
this.SendPropertyChanging();
this._Style = value;
this.SendPropertyChanged("Style");
this.OnStyleChanged();
}
}
}
[DataMember]
[Column(Storage="_ProductSubcategoryID", DbType="Int")]
public System.Nullable<int> ProductSubcategoryID
{
get
{
return this._ProductSubcategoryID;
}
set
{
if ((this._ProductSubcategoryID != value))
{
this.OnProductSubcategoryIDChanging(value);
this.SendPropertyChanging();
this._ProductSubcategoryID = value;
this.SendPropertyChanged("ProductSubcategoryID");
this.OnProductSubcategoryIDChanged();
}
}
}
[DataMember]
[Column(Storage="_ProductModelID", DbType="Int")]
public System.Nullable<int> ProductModelID
{
get
{
return this._ProductModelID;
}
set
{
if ((this._ProductModelID != value))
{
this.OnProductModelIDChanging(value);
this.SendPropertyChanging();
this._ProductModelID = value;
this.SendPropertyChanged("ProductModelID");
this.OnProductModelIDChanged();
}
}
}
[DataMember]
[Column(Storage="_SellStartDate", DbType="DateTime NOT NULL")]
public System.DateTime SellStartDate
{
get
{
return this._SellStartDate;
}
set
{
if ((this._SellStartDate != value))
{
this.OnSellStartDateChanging(value);
this.SendPropertyChanging();
this._SellStartDate = value;
this.SendPropertyChanged("SellStartDate");
this.OnSellStartDateChanged();
}
}
}
[DataMember]
[Column(Storage="_SellEndDate", DbType="DateTime")]
public System.Nullable<System.DateTime> SellEndDate
{
get
{
return this._SellEndDate;
}
set
{
if ((this._SellEndDate != value))
{
this.OnSellEndDateChanging(value);
this.SendPropertyChanging();
this._SellEndDate = value;
this.SendPropertyChanged("SellEndDate");
this.OnSellEndDateChanged();
}
}
}
[DataMember]
[Column(Storage="_DiscontinuedDate", DbType="DateTime")]
public System.Nullable<System.DateTime> DiscontinuedDate
{
get
{
return this._DiscontinuedDate;
}
set
{
if ((this._DiscontinuedDate != value))
{
this.OnDiscontinuedDateChanging(value);
this.SendPropertyChanging();
this._DiscontinuedDate = value;
this.SendPropertyChanged("DiscontinuedDate");
this.OnDiscontinuedDateChanged();
}
}
}
[DataMember]
[Column(Storage="_rowguid", DbType="UniqueIdentifier NOT NULL")]
public System.Guid rowguid
{
get
{
return this._rowguid;
}
set
{
if ((this._rowguid != value))
{
this.OnrowguidChanging(value);
this.SendPropertyChanging();
this._rowguid = value;
this.SendPropertyChanged("rowguid");
this.OnrowguidChanged();
}
}
}
[DataMember]
[Column(Storage="_ModifiedDate", DbType="DateTime NOT NULL")]
public System.DateTime ModifiedDate
{
get
{
return this._ModifiedDate;
}
set
{
if ((this._ModifiedDate != value))
{
this.OnModifiedDateChanging(value);
this.SendPropertyChanging();
this._ModifiedDate = value;
this.SendPropertyChanged("ModifiedDate");
this.OnModifiedDateChanged();
}
}
}
public event PropertyChangingEventHandler PropertyChanging;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void SendPropertyChanging()
{
if ((this.PropertyChanging != null))
{
this.PropertyChanging(this, emptyChangingEventArgs);
}
}
protected virtual void SendPropertyChanged(String propertyName)
{
if ((this.PropertyChanged != null))
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
#pragma warning restore 1591
第四步:创建一个启动了Ajax支持的WCF服务:PageGridService.svc
设计一个用于与ExtJs进行分页交互的PageData泛型类:
using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Runtime.Serialization;
namespace ExtJs_Wcf_Linq_PageGrid
{
[DataContract]
public class PageData<T>
{
[DataMember]
public int TotolRecord
{
get;
set;
}
[DataMember]
public T Data
{
get;
set;
}
}
}
这个泛型类用于WCF与ExtJS的Grid控件交互,T是返回的具体数据类型的集合,TotalRecord是总记录数。
修改PageGridService.svc的页面代码,添加Factory="System.ServiceModel.Activation.WebServiceHostFactory",添加后代码如下:
在后台代码中设计一个WCF服务操作,用于与ExtJS交互:
public PageData<Product[]> GetProductsByPage(int start,int limit)
具体代码为:
[OperationContract]
[WebInvoke(Method = "*", ResponseFormat = WebMessageFormat.Json,
UriTemplate = "GetProductsByPage?start={start}&limit={limit}")]
public PageData<Product[]> GetProductsByPage(int start,int limit)
{
ProductsDataContext productDbContext = new ProductsDataContext();
IQueryable<Product> res = productDbContext.Product.Select(product => product);
PageData<Product[]> returnData = new PageData<Product[]>();
returnData.TotolRecord = res.ToArray<Product>().Length;
res = res.Skip<Product>(start);
res = res.Take<Product>(limit);
returnData.Data = res.ToArray<Product>();
return returnData;
}
注意在linq中用Skip和Take实现分页
第五步:创建htm页面PageGridDemo.htm,添加如下的代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>ExtJs+WCF+LINQ打造分页Grid</title>
<link rel="stylesheet" type="text/css" href="resources/css/ext-all.css" />
<script type="text/javascript" src="adapter/ext/ext-base.js" charset="gb2312"></script>
<script type="text/javascript" src="ext-all.js" charset="gb2312"></script>
<link rel="stylesheet" type="text/css" href="shared/examples.css" />
<script type="text/javascript" src="shared/examples.js" charset="gb2312"></script>
<script type="text/javascript" src="pagegrid.js" charset="gb2312"></script>
</head>
<body>
<h1>
ExtJs+WCF+LINQ打造分页Grid</h1>
<div id="page-grid">
</div>
</body>
</html>
第六步: 创建javascript脚本文件,用于实现ExtJs grid控件,代码为:
/**//*
* Ext JS Library 2.1
* Copyright(c) 2006-2008, Ext JS, LLC.
* licensing@extjs.com
*
* http://extjs.com/license
*/
Ext.onReady(function(){
//创建一个用于访问WCF服务的HttpProxy,且访问方法为GET
var proxy = new Ext.data.HttpProxy({
url:'PageGridService.svc/GetProductsByPage',
method:'GET'
});
var reader = new Ext.data.JsonReader(
{root:'Data',totalProperty :'TotolRecord'},
[
{name: 'ProductID'},
{name: 'Name'},
{name: 'ProductNumber'},
{name: 'MakeFlag'},
{name: 'FinishedGoodsFlag'},
{name: 'Color'},
{name: 'SafetyStockLevel'},
{name: 'ReorderPoint'},
{name: 'StandardCost'},
{name: 'ListPrice'},
{name: 'Size'},
{name: 'SizeUnitMeasureCode'},
{name: 'Weight'},
{name: 'DaysToManufacture'},
{name: 'ProductLine'},
{name: 'Class'},
{name: 'Style'},
{name: 'Weight'},
{name: 'ProductSubcategoryID'},
{name: 'ProductModelID'},
{name: 'SellStartDate'},
{name: 'SellEndDate'},
{name: 'DiscontinuedDate'},
{name: 'rowguid'},
{name: 'ModifiedDate'}
]
);
var store = new Ext.data.Store(
{proxy:proxy,reader:reader}
);
// create the Grid
var grid = new Ext.grid.GridPanel({
store: store,
columns: [
{id:'ProductID',header: "编号",width:30, sortable: true, dataIndex: 'ProductID'},
{header: "名称", width:75, sortable: true, dataIndex: 'Name'},
{header: "产品编码", width:75, sortable: true, dataIndex: 'ProductNumber'},
{header: "是否标记", width:75, sortable: true, dataIndex: 'MakeFlag'},
{header: "颜色", width:50, sortable: true,dataIndex:'Color'},
{header: "数量", width:50, sortable: true,dataIndex:'ReorderPoint'},
{header: "单价", width:50, sortable: true,renderer:'userMoney',dataIndex: 'StandardCost'}
],
stripeRows: true,
autoExpandColumn: 'ProductID',
height:400,
width:600,
title:'产品信息',
viewConfig:
{
columnsText:'列',
sortAscText:'升序',
sortDescText:'降序'
},
bbar: new Ext.PagingToolbar({
pageSize: 25,
store: store,
displayInfo: true,
displayMsg: '总记录数 {0} - {1} of {2}',
emptyMsg: "没有记录"
})
});
grid.render('page-grid');
//载入
store.load({params:{start:0,limit:25}});
grid.getSelectionModel().selectFirstRow();
});
好,到此,一个ExtJs+Wcf+LINQ分页Grid实现完毕,下面浏览PageGridDemo.htm,查看运行效果:
国际惯例,上示例项目文件: /Files/jillzhang/ExtJs_Wcf_Linq_PageGrid.rar
出处:http://jillzhang.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。