Asp.net 如何在MVC中传递一个模型,使我不';不必查询数据库两次?
我想在页面上创建一个导出模型的超链接,但不想为需要导出的每个模型编写方法。我希望最终得到一个方法,该方法可以将模型作为其参数之一,并对该模型执行导出逻辑。是否有一种方法可以将发送到视图的模型传递回控制器操作 编辑:Asp.net 如何在MVC中传递一个模型,使我不';不必查询数据库两次?,asp.net,asp.net-mvc,razor,Asp.net,Asp.net Mvc,Razor,我想在页面上创建一个导出模型的超链接,但不想为需要导出的每个模型编写方法。我希望最终得到一个方法,该方法可以将模型作为其参数之一,并对该模型执行导出逻辑。是否有一种方法可以将发送到视图的模型传递回控制器操作 编辑: @model WebTools.Models.PenDailyViewModel <table> <thead>Header Stuff</thead> <tbody> @foreach (var item i
@model WebTools.Models.PenDailyViewModel
<table>
<thead>Header Stuff</thead>
<tbody>
@foreach (var item in Model.penDaily)
{
//Generate table body
}
</tbody>
<tfoot>
@foreach (var item in Model.penSummary)
{
//Generate table footer
}
</tfoot>
</table>
我有以下控制员行动-
public ViewResult PenDaily(Nullable<DateTime> startDate = null, Nullable<DateTime> endDate = null, string listName = "")
{
//Removed code for brevity/clarity
PenDailyViewModel penDailyView = new PenDailyViewModel();
penDailyView.startDate = startDate;
penDailyView.endDate = endDate;
penDailyView.listNames = GetLists(m_db);
penDailyView.penDaily = GeneratePenDaily(m_db, listName, startDate, endDate);
penDailyView.penSummary = GeneratePenSummary(m_db, startDate, endDate, "").Where(a => a.listName == listName);
return View(penDailyView);
}
public ViewResult PenDaily(可空的startDate=null,可空的endDate=null,字符串listName=”“)
{
//为了简洁/清晰,删除了代码
penDailyView模型penDailyView=新penDailyView模型();
penDailyView.startDate=startDate;
penDailyView.endDate=endDate;
penDailyView.listNames=GetLists(m_db);
penDailyView.penDaily=GeneratePenDaily(m_db,listName,startDate,endDate);
penDailyView.penSummary=generateEnsummary(m_db,startDate,endDate,“”),其中(a=>a.listName==listName);
返回视图(penDailyView);
}
PenDailyViewModel是传递给Razor视图的模型对象。PenDaily和PenSummary都是可在结果页的表中使用的IQueryable对象。PenDaily是主数据集,PenSummary用于表尾的总行
我想获取这组数据并将其导出到文件中。我写了一个函数来实现这一点,但我不知道如何从我的页面使用它。我想设置这样,当用户单击超链接时,会提示他们保存导出
如果有帮助,我的剃须刀视图:
@model WebTools.Models.PenDailyViewModel
<table>
<thead>Header Stuff</thead>
<tbody>
@foreach (var item in Model.penDaily)
{
//Generate table body
}
</tbody>
<tfoot>
@foreach (var item in Model.penSummary)
{
//Generate table footer
}
</tfoot>
</table>
@model WebTools.Models.PenDailyViewModel
标题材料
@foreach(Model.penDaily中的var项)
{
//生成表体
}
@foreach(Model.penSummary中的var项)
{
//生成表尾
}
在隐藏的表单字段中传递要返回的数据,然后使用表单而不是简单的超链接将呼叫返回给控制器。然后,它将接收来自隐藏字段的数据
这是一个真正的页面状态,而不是可能与页面状态不同步的会话状态(使用后退按钮、打开另一个选项卡/窗口等)
也就是说,如果查询很便宜(因此速度很快),那么访问DB不一定是件坏事。就我个人而言,我总是为视图(即a
GET
)或任何帖子创建单独的模型
IndexViewModel
IndexInputModel
很多时候,这些poco非常相似
现在的诀窍可能是利用AutoMapper
,这样您就可以更容易地支持/维护代码,而不是使用大量从左到右的代码(例如foo=viewmodel.foo)
其思想是:您有一个在控制器中使用的基类库对象。这是POCO的主要目标。接下来,您将看到与此POCO的模式/结构直接相关的视图模型和输入模型。使用AutoMapper(或者大量从左到右的代码,如果您还不熟悉这个编程工具的话),您可以轻松地在相关对象之间“复制”数据
例如
示例视图
视图模型
public class IndexViewModel
{
public string Name { get; set; }
public string Description { get; set; }
public Uri InfoUrl { get; set; }
}
(视图)操作方法(错误检查等)
除非我遗漏了什么,否则你能不能将你的实体从数据库上下文中分离出来,并将其存储在ASP.NET会话中,以便在另一个请求中使用?@SeanGlover我想,我真的不知道我的选择是什么。我只是想找出实现我的目标的最佳途径:导出数据,而不必编写多个函数或多次访问数据库。我不清楚您想要做什么。当你应该问如何完成你的实际问题时,你似乎在问一个你所面临的问题的解决方案,试图解决你真正的问题。提供一个你想做什么的代码示例,并更详细地解释它应该做什么。@Kittoes我们需要看一些实际的代码。您使用的是model
这个词,而不是。。。乔治斯托克似乎做了大量的工作,并进一步解释了我所拥有的以及我的目标是什么。我所说的模型是指Razor视图使用的模型。使用不是为了自由,而是为了具体。这没关系,只要数据不是为每个用户定制的。否则缓存将相互覆盖,并可能显示用户不应该看到的信息(或不让其他用户看到他们应该看到的信息)。在这类事情上你必须非常小心。@MystereMan缓存设置为保存公共信息。数据库中的某些内容是unqiue。所以缓存会在内存中保存这些信息。然后将结果“自定义”到视图中。海报的主要目的是,当他们对“看起来”相同的数据进行2次或更多回调时,减少到db的往返次数。所以“缓存”所有的东西。缓存数据库结果,然后将自定义视图投影给用户。@Downvoter,请发表评论,以便我知道为什么我的答案不好?我没有投票给你,但我不确定你的解决方案是否适合我的问题。当然,第二次访问数据库一点也不贵,但我已经在屏幕上以列表形式显示了数据。我认为将相同的数据以几乎与显示格式完全相同的格式导出到一个文件是非常简单的。@Kittoes,创建一个文件并重新读取可能与DB查询一样昂贵,并且会产生其他问题(这些文件要保存多久等)。我完全同意,我只希望它在客户端生成。
// product/{id} eg /products/5
public Action Index()
{
// Load the Product from your cache
var product = YourCache.Load(id);
if (product == null)
{
return NotFound("Product can't be found.");
}
// Convert the product to this view requirements.
// This will copy over the Name and the Uri.
var model = Mapper.Map<Product, IndexViewModel>(product);
return View(model);
}
public class YourCache
{
private static ObjectCache cache = MemoryCache.Default;
private IRepository Repository { get; set; }
public YourCache(IRepository repository)
{
Repository = repository;
}
public Product Load(int id)
{
var product = cache["Product-" + id] as Product;
if (product == null)
{
// Grab it and remember it.
product = repository.Load(id);
if (product != null)
{
cache.Set("Product-" + id, product, ....);
}
}
return product;
}
}