我有一个视图模型:
public class UserCollectionView
{
public CardCollection CardCollections { get; set; }
public Card Cards { get; set; }
}
我有一个列表视图控制器:
public ActionResult ViewCollection(int? page)
{
var userid = (int)WebSecurity.CurrentUserId;
var pageNumber = page ?? 1;
int pageSize = 5;
ViewBag.OnePageOfCards = pageNumber;
if (Session["CardCollection"] != null)
{
var paging = Session["CardCollection"].ToString.();
return View(paging.ToPagedList(pageNumber, pageSize));
}
var viewModel = from c in db.Cards
join j in db.CardCollections on c.CardID equals j.CardID
where (j.NumberofCopies > 0) && (j.UserID == userid)
orderby c.Title
select new UserCollectionView { Cards = c, CardCollections = j };
Session["CardCollection"] = viewModel;
return View(viewModel.ToPagedList(pageNumber, pageSize));
我正在尝试使用PagedList向结果添加分页。当我没有使用在单个视图中从2个数据库返回数据的查询时,我能够这样做。 As shown here
我的最终结果如下:
Cards.SeveralColumns CardCollections.ColumnA CardCollections.ColumnB
Row 1 Data from Cards Table A from CardCollections B from CardCollections
Row 2 Data from Cards Table A from CardCollections B from CardCollections
Row 3 Data from Cards Table A from CardCollections B from CardCollections
等等...我收到了一个错误
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
我尝试过各种SQL语句,但不能使它适合我的视图模型。在SQL Management Studio中,这会返回正确的结果
Select * from Cards Inner Join CardCollections On Cards.CardID = CardCollections.CardID where CardCollections.UserID = 1 and CardCollections.NumberofCopies > 0;
我需要一种在会话中传递查询的方法,以便分页正常运行。任何建议表示赞赏。 :)
答案 0 :(得分:2)
简短的回答是,你不能。模型需要是内容的快照,因此您无法跨越边界传递打开的查询(作为会话或直接传递给客户端)。
您所看到的是处理超出其初始使用范围的上下文(汇集var viewmodel
的地方)。
话虽如此,如果查询数据是一项昂贵的操作,您可以缓存结果(以节省开销)。基本上,您将整个集合(或至少是集合的一个大部分)存储在session / memorycache中(然后可以将其操作到分页列表中)。有什么影响:
public ActionResult ViewCollection(int? page)
{
var userId = (int) WebSecurity.CurrentUserId;
var pageNumber = page ?? 1;
var pageSize = 5;
ViewBag.OnePageOfCards = pageNumber;
var cacheKey = String.Format("ViewCollection[{0}]", userId);
var entities = GetOrCreateCacheItem<IEnumerable<UserCollectionView>>(cacheKey, () => {
var query = (from c in db.Cards
join j in db.CardCollections on c.CardID equals j.CardID
where (j.NumberofCopies > 0) && (j.UserID == userid)
orderby c.Title
select new UserCollectionView { Cards = c, CardCollections = j }
)
.ToList(); // Force fetch from Db so we can cache
});
return View(entities.ToPagedList(pageNumber, pageSize));
}
// To give an example of a cache provider; Feel free to change this,
// abstract it out, etc.
private T GetOrCreateCacheItem<T>(string cacheKey, Func<T> getItem)
{
T cacheItem = MemoryCache.Default.Get(cacheKey) as T;
if (cacheItem == null)
{
cacheItem = getItem();
var cacheExpiry = DateTime.Now.AddMinutes(5);
MemoryCache.Default.Add(cacheKey, cacheItem, cacheExpiry);
}
return cacheItem;
}
答案 1 :(得分:0)
事实证明,我根本不需要传递查询。如果我让它运行它没有会话工作正常。我不确定为什么这样做但我的搜索查询必须通过。也许是因为我使用viewmodel来执行查询。如果我找到任何东西,我会试验并发布。目前工作代码是:
public ActionResult ViewCollection(int? page)
{
var userid = (int)WebSecurity.CurrentUserId;
var pageNumber = page ?? 1;
int pageSize = 5;
ViewBag.OnePageOfCards = pageNumber;
ViewBag.Rarity_ID = new SelectList(db.Rarities, "RarityID", "Title");
ViewBag.MainType_ID = new SelectList(db.MainTypes, "MainTypeID", "Title");
ViewBag.CardSet_ID = new SelectList(db.CardSets, "CardSetID", "Title");
ViewBag.SubType_ID = new SelectList(db.SubTypes, "SubTypeID", "Title");
var viewModel = from c in db.Cards
join j in db.CardCollections on c.CardID equals j.CardID
where (j.NumberofCopies > 0) && (j.UserID == userid)
orderby c.Title
select new UserCollectionView { Cards = c, CardCollections = j };
return View(viewModel.ToPagedList(pageNumber, pageSize));