Linq to Entites 分页

Linq To Entities 提供了分页的函数,Skip与Take

如下方法

  
public PagedList(IEnumerable < T > source, int index, int pageSize)
{
this .TotalCount = source.Count();
this .PageSize = pageSize;
this .PageIndex = index;

base .AddRange(source.Skip < T > (((index - 1 ) * pageSize)).Take < T > (pageSize).ToList < T > ());
this .TotalPages = (( this .TotalCount - 1 ) / pageSize) + 1 ;
}

可是source.Count()放到项目中是有问题的,这个Count执行的时候会要的时间非常久。开Reflector查看,后发现原来微软写的一个静态Queryable,在里面定义了很多的扩展方法,接受ObjectQuery 等各种Query的方法,我想应该就是生成SQL语句等吧。

后将代码修改为:

  
public PagedList(ObjectQuery < T > source, int index, int pageSize)
{
this .TotalCount = source.Count();
this .PageSize = pageSize;
this .PageIndex = index;

base .AddRange(source.Skip < T > (((index - 1 ) * pageSize)).Take < T > (pageSize).ToList < T > ());
this .TotalPages = (( this .TotalCount - 1 ) / pageSize) + 1 ;
}

然后在调用的时候

  
public static PagedList < T > ToPagedList < T > ( this IEnumerable < T > source, int ? pageIndex, int pageSize)
{
if (source is IOrderedQueryable < T > )
return ToPagedList(source as ObjectQuery < T > , pageIndex, pageSize);

if (source is IQueryable < T > )
return ToPagedList(source as ObjectQuery < T > , pageIndex, pageSize);

if (source is ObjectQuery < T > )
return ToPagedList(source as ObjectQuery < T > , pageIndex, pageSize);

int index = Convert.ToInt32(pageIndex);

if (index < 1 )
{
index
= 1 ;
}

return new PagedList < T > (source, index, pageSize);
}

后是可以运行了,但是运行之后报了一个错:仅对 LINQ to Entities 中已排序的输入支持方法“Skip”。必须在调用“Skip”方法之前调用方法“OrderBy”。

这下惨了,这个项目很大,很多地方用到分页,我不可能一个一个去改,而且部署了很多地方。后来想到了一个不是解决办法的办法,从ObjectContext的Metadata获取主键信息,然后保存起来每次对他的主键进行OrderBy

  
Intenal class ContextMetDatePrimary
{
static Dictionary < string , List < string >> primary = new Dictionary < string , List < string >> ();

public static Dictionary < string , List < string >> Primary
{
get { return ContextMetDatePrimary.primary; }
}

public static void SetContextMetDatePrimary(Type t)
{
object o = Activator.CreateInstance(t);

Type ot
= o.GetType();

MetadataWorkspace work
= (MetadataWorkspace)ot.GetProperty( " MetadataWorkspace " ).GetValue(o, null );

SetContextMetDatePrimary(work);

ot.InvokeMember(
" Dispose " , BindingFlags.InvokeMethod, null , o, null );
}

public static void SetContextMetDatePrimary(MetadataWorkspace work)
{
foreach (var i in work.GetItems < EntityType > (DataSpace.CSpace))
{
List
< string > p = new List < string > ();

foreach (var key in i.KeyMembers)
{
p.Add(key.Name);
}

if ( ! primary.ContainsKey(i.Name))
primary.Add(i.Name, p);
}
}

public static List < string > GetPrimaryKey( string tableName)
{
return primary[tableName];
}
}
总算弄成了

你可能感兴趣的:(LINQ)