使用MVC和Linq to SQL来了解一些基本原理我正在努力改编Stephen Walther的TaskList application:
我正在使用Steve Sanderson's blog中描述的概念添加批量修改系统。
这一切都按预期工作,但是,我在保存返回的任务列表时遇到问题。发布到我的BulkEdit循环返回列表并更新我的LinqToSql db任务列表中的每个项目。
我的BulkEdit视图继承ViewPage<List<TaskList.Models.Task>>
,如下所示:
<%
using (Html.BeginForm())
{
%>
<div id="items">
<%
foreach (var task in ViewData.Model)
{
Html.RenderPartial(
"TaskEditor",
task,
new ViewDataDictionary(ViewData)
{
{"prefix", "tasks"}
}
);
}
%>
</div>
<input type="submit" value="Save changes" />
<%
}
%>
TaskEditor控件继承System.Web.Mvc.ViewUserControl<Models.Task>
,如下所示:
<div>
<%= Html.Hidden(ViewData["prefix"] + ".index", ViewData.Model.Id) %>
<% var fieldPrefix = string.Format("{0}[{1}].", ViewData["prefix"], ViewData.Model.Id); %>
<%= Html.Hidden(fieldPrefix + "Id", ViewData.Model.Id) %>
Description:
<%= Html.TextBox(fieldPrefix + "TaskDescription", ViewData.Model.TaskDescription)%>
Date:
<%= Html.TextBox(fieldPrefix + "EntryDate", ViewData.Model.EntryDate.ToString("o"))%>
Completed:
<%= Html.CheckBox(fieldPrefix + "IsCompleted", ViewData.Model.IsCompleted)%>
</div>
Controller Get和Post方法如下:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult BulkEdit()
{
var tasks = from t in db.Tasks orderby t.EntryDate descending select t;
return View(tasks.ToList());
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult BulkEdit(IList<Task> tasks)
{
foreach(Task task in tasks)
{
foreach(Task dbTask in db.Tasks)
{
if (dbTask.Id == task.Id)
{
dbTask.TaskDescription = task.TaskDescription;
dbTask.EntryDate = task.EntryDate;
dbTask.IsCompleted = task.IsCompleted;
}
}
}
db.SubmitChanges();
return RedirectToAction("Index");
}
我的问题是,这似乎太复杂了,我还没有考虑从列表中添加或删除的任务。我更喜欢做的事情就像
db.Tasks = tasks;
让Linq尽其所能来解决哪些已发生变化以及哪些是新的/旧的。
这可能吗?或者我很快就会期待Linq有点太过分了?
答案 0 :(得分:3)
您正在处理LINQ to SQL没有多层故事的事实。我认为这就是你要找的东西:
http://blog.irm.se/blogs/eric/archive/2008/08/20/Go-Distributed-With-LINQ-to-SQL.aspx
这个人提出的Merge方法可以很容易地变成DataContext类的“扩展方法”,它几乎就像是在LINQ to SQL中构建的。我说几乎是因为你必须包含你的扩展方法所在的命名空间才能使用它。
答案 1 :(得分:0)
我认为您应该考虑使用视图来完成您想要的任务。用于保存项目的ObservebleCollection集合,然后您可以在列表中绑定到该集合的视图,您仍然需要处理添加和删除项目的情况,但您也可以选择一个IBindingList来为您提供一个将更新数据库的BindingListCollectionView,您需要做的就是调用视图AddNew()CommitNew()等等。
HTH, 埃里克