Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实施IPagedList<;T>;在我使用NHibernate的模型上_C#_Asp.net_Nhibernate_Interface_Asp.net 3.5 - Fatal编程技术网

C# 实施IPagedList<;T>;在我使用NHibernate的模型上

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

我发现,当使用NHibernate并在对象上创建一对多关系时,当多对象变得非常大时,它会显著减慢速度。现在,我的存储库中确实有收集这种类型的分页IList的方法,但是我更希望在模型上也有这些方法,因为其他开发人员通常会首先在模型上收集子对象列表

e、 g

RecipientList。收件人将返回列表中的每个收件人

我想实现一种方法,将所有oen上的分页添加到模型中的许多关系中,最好使用一个接口,但实际上任何不会将类型化关系强制到模型上的东西。例如,最好有以下界面:

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;
    }
}