C# 实施IPagedList<;T>;在我使用NHibernate的模型上
我发现,当使用NHibernate并在对象上创建一对多关系时,当多对象变得非常大时,它会显著减慢速度。现在,我的存储库中确实有收集这种类型的分页IList的方法,但是我更希望在模型上也有这些方法,因为其他开发人员通常会首先在模型上收集子对象列表 e、 g RecipientList。收件人将返回列表中的每个收件人 我想实现一种方法,将所有oen上的分页添加到模型中的许多关系中,最好使用一个接口,但实际上任何不会将类型化关系强制到模型上的东西。例如,最好有以下界面:C# 实施IPagedList<;T>;在我使用NHibernate的模型上,c#,asp.net,nhibernate,interface,asp.net-3.5,C#,Asp.net,Nhibernate,Interface,Asp.net 3.5,我发现,当使用NHibernate并在对象上创建一对多关系时,当多对象变得非常大时,它会显著减慢速度。现在,我的存储库中确实有收集这种类型的分页IList的方法,但是我更希望在模型上也有这些方法,因为其他开发人员通常会首先在模型上收集子对象列表 e、 g RecipientList。收件人将返回列表中的每个收件人 我想实现一种方法,将所有oen上的分页添加到模型中的许多关系中,最好使用一个接口,但实际上任何不会将类型化关系强制到模型上的东西。例如,最好有以下界面: public interfac
public interface IPagedList<T> : IList<T>
{
int Count { get; }
IList<T> GetPagedList(int pageNo, int pageSize);
IList<T> GetAll();
}
公共接口IPagedList:IList
{
整数计数{get;}
IList GetPagedList(int pageNo,int pageSize);
IList GetAll();
}
然后能够在代码中使用它
IList<Recipient> recipients = RecipientList.Recipients.GetPagedList(1, 400);
IList recipients=RecipientList.recipients.GetPagedList(1400);
我一直在想办法做到这一点,但没有给模型任何分页的意识,但我的头撞到了砖墙的时刻
我是否可以用NHibernate目前用于IList和lazyloading的类似方式实现该接口?我对NHibernate的了解还不够
实现这一点是个好主意吗?作为本公司唯一的.NET开发人员,您的想法将不胜感激,因为我没有人能提出您的想法
更新
下面的帖子向我指出了NHibernate的自定义集合属性,这将很好地工作。但是,我不确定解决这个问题的最佳方法是什么,我尝试从PersistentGenericBag继承,这样它就具有与IList相同的基本功能,而无需做太多工作,但是我不确定如何根据ISessionImplementor收集对象列表。我需要知道如何:
- 获取我将要填充的当前IList的一些ICriteria详细信息
- 获取与IList关联的特定属性的映射详细信息,以便我可以创建自己的ICriteria李>
谢谢如果你打算这样做,我想不出一个办法,你可以“写”到页面集合中,让NH持久化。分页的集合将是只读的 如果可以,那么您可以使用如下方法: 他正在包装PersistentGenericBag并添加一些ekstra方法,正如您所描述的。GetPagedList()可以使用一个条件来实现,该条件返回一个ReadOnlyCollection,也可以计数-当然返回一个long。GetAll()方法不是必需的,就我所见,它只是返回集合本身
至于这是否是一个好主意,我确实认为是,如果你有很多收藏,这是一个实际问题。如果只是一个或两个collection,我会选择在实体上有一个方法,它自己返回页面中的集合。好的,我将把它作为一个答案发布,因为它正在做我想做的事情。然而,我希望得到一些反馈,也可能是我迄今为止对解决方案的一个警告的答案: 我创建了一个名为IPagedList的接口
public interface IPagedList<T> : IList<T>, ICollection
{
IList<T> GetPagedList(int pageNo, int pageSize);
}
公共接口IPagedList:IList,ICollection
{
IList GetPagedList(int pageNo,int pageSize);
}
然后创建了从IPagedList继承的基类:
public class PagedList<T> : IPagedList<T>
{
private List<T> _collection = new List<T>();
public IList<T> GetPagedList(int pageNo, int pageSize)
{
return _collection.Take(pageSize).Skip((pageNo - 1) * pageSize).ToList();
}
public int IndexOf(T item)
{
return _collection.IndexOf(item);
}
public void Insert(int index, T item)
{
_collection.Insert(index, item);
}
public void RemoveAt(int index)
{
_collection.RemoveAt(index);
}
public T this[int index]
{
get
{
return _collection[index];
}
set
{
_collection[index] = value;
}
}
public void Add(T item)
{
_collection.Add(item);
}
public void Clear()
{
_collection.Clear();
}
public bool Contains(T item)
{
return _collection.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
_collection.CopyTo(array, arrayIndex);
}
int Count
{
get
{
return _collection.Count;
}
}
public bool IsReadOnly
{
get { return false; }
}
public bool Remove(T item)
{
return _collection.Remove(item);
}
public IEnumerator<T> GetEnumerator()
{
return _collection.GetEnumerator();
}
int ICollection<T>.Count
{
get { return _collection.Count; }
}
IEnumerator IEnumerable.GetEnumerator()
{
return _collection.GetEnumerator();
}
public void CopyTo(Array array, int index)
{
T[] arr = new T[array.Length];
for (int i = 0; i < array.Length ; i++)
{
arr[i] = (T)array.GetValue(i);
}
_collection.CopyTo(arr, index);
}
int ICollection.Count
{
get { return _collection.Count; }
}
// The IsSynchronized Boolean property returns True if the
// collection is designed to be thread safe; otherwise, it returns False.
public bool IsSynchronized
{
get
{
return false;
}
}
public object SyncRoot
{
get
{
return this;
}
}
}
公共类页面列表:IPagedList
{
私有列表_collection=新列表();
公共IList GetPagedList(int pageNo,int pageSize)
{
return _collection.Take(pageSize).Skip((pageNo-1)*pageSize.ToList();
}
公共整数索引(T项)
{
返回_collection.IndexOf(项目);
}
公共空白插入(整数索引,T项)
{
_收藏。插入(索引,项目);
}
公共无效删除(整数索引)
{
_收集、删除(索引);
}
公共T此[int索引]
{
得到
{
返回集合[索引];
}
设置
{
_集合[索引]=值;
}
}
公共作废新增(T项)
{
_集合。添加(项目);
}
公共空间清除()
{
_collection.Clear();
}
公共布尔包含(T项)
{
返回_集合。包含(项目);
}
public void CopyTo(T[]数组,int arrayIndex)
{
_collection.CopyTo(数组、数组索引);
}
整数计数
{
得到
{
返回_collection.Count;
}
}
公共图书馆是只读的
{
获取{return false;}
}
公共布尔删除(T项)
{
退货_收款。删除(项目);
}
公共IEnumerator GetEnumerator()
{
返回_collection.GetEnumerator();
}
int ICollection.Count
{
获取{return\u collection.Count;}
}
IEnumerator IEnumerable.GetEnumerator()
{
返回_collection.GetEnumerator();
}
public void CopyTo(数组,int索引)
{
T[]arr=新的T[array.Length];
for(int i=0;i
然后,我创建一个IUserCollectionType供NHibernate用作自定义集合类型和NHPagedList,它继承自PersistentGenericBag、IPagedL
public class PagedListFactory<T> : IUserCollectionType
{
public PagedListFactory()
{ }
#region IUserCollectionType Members
public bool Contains(object collection, object entity)
{
return ((IList<T>)collection).Contains((T)entity);
}
public IEnumerable GetElements(object collection)
{
return (IEnumerable)collection;
}
public object IndexOf(object collection, object entity)
{
return ((IList<T>)collection).IndexOf((T)entity);
}
public object Instantiate(int anticipatedSize)
{
return new PagedList<T>();
}
public IPersistentCollection Instantiate(ISessionImplementor session, ICollectionPersister persister)
{
return new NHPagedList<T>(session);
}
public object ReplaceElements(object original, object target, ICollectionPersister persister,
object owner, IDictionary copyCache, ISessionImplementor session)
{
IList<T> result = (IList<T>)target;
result.Clear();
foreach (object item in ((IEnumerable)original))
{
result.Add((T)item);
}
return result;
}
public IPersistentCollection Wrap(ISessionImplementor session, object collection)
{
return new NHPagedList<T>(session, (IList<T>)collection);
}
#endregion
}
public class NHPagedList<T> : PersistentGenericBag<T>, IPagedList<T>
{
public NHPagedList(ISessionImplementor session) : base(session)
{
_sessionImplementor = session;
}
public NHPagedList(ISessionImplementor session, IList<T> collection)
: base(session, collection)
{
_sessionImplementor = session;
}
private ICollectionPersister _collectionPersister = null;
public NHPagedList<T> CollectionPersister(ICollectionPersister collectionPersister)
{
_collectionPersister = collectionPersister;
return this;
}
protected ISessionImplementor _sessionImplementor = null;
public virtual IList<T> GetPagedList(int pageNo, int pageSize)
{
if (!this.WasInitialized)
{
IQuery pagedList = _sessionImplementor
.GetSession()
.CreateFilter(this, "")
.SetMaxResults(pageSize)
.SetFirstResult((pageNo - 1) * pageSize);
return pagedList.List<T>();
}
return this
.Skip((pageNo - 1) * pageSize)
.Take(pageSize)
.ToList<T>();
}
public new int Count
{
get
{
if (!this.WasInitialized)
{
return Convert.ToInt32(_sessionImplementor.GetSession().CreateFilter(this, "select count(*)").List()[0].ToString());
}
return base.Count;
}
}
}
.CollectionType<PagedListFactory<Recipient>>()
public abstract class Repository<T> where T: class
{
public abstract T GetByID(int id);
public abstract IQueryable<T> GetAll();
public abstract T Insert(T entity);
public abstract void Update(T entity);
public abstract void Delete(T entity);
}
public class RecipientRepository: Repository<Recipient>;
{
// ...
public override IQueryable<Recipient> GetAll()
{
using (ISession session = /* get session */)
{
// Gets a query that will return all Recipient entities if iterated
IQueryable<Recipient> query = session.Linq<Recipient>();
return query;
}
}
// ...
}
public class RecipientList
{
public IQueryable<Recipient> Recipients
{
RecipientRepository repository = new RecipientRepository();
return repository.GetAll(); // Returns a query, does not evaluate, so does not hit database
}
}
// Consuming RecipientList in some higher level service, you can now do:
public class RecipientService
{
public IList<Recipient> GetPagedList(int page, int size)
{
RecipientList list = // get instance of RecipientList
IQueryable<Recipient> query = list.Recipients.Skip(page*size).Take(size); // Get your page
IList<Recipient> listOfRecipients = query.ToList(); // <-- Evaluation happens here!
reutrn listOfRecipients;
}
}