2009-08-14 62 views
1

是否有预构建的ModelBinder可以与LINQ一起使用从DataContext获取对象并在HTTP Post上更新它?ASP.NET MVC,LINQ和ModelBinders

例如,目前我的代码块:

[AcceptVerbs (HttpVerbs.Post)] 
public ActionResult Edit (Project project) 
{ 
    var projectService = Factory.GetService<IProjectService>(); 
    project = projectService.GetProject (project.ProjectId); 

    UpdateModel<Project> (project); 

    if (!ModelState.IsValid) 
     return View (project); 

    project = projectService.SaveProject (project); 

    return RedirectToAction ("Details", new { id = project.ProjectId }); 
} 

(IProjectService包扎呼叫到LINQ数据上下文)

为了实际经由LINQ执行更新到数据库数据上下文,我需要再次获取项目实例,然后更新该实例。

任何尝试简单地保存项目实例而不先从数据上下文中获取结果都不会将任何内容写回数据库 - 我假设因为LINQ数据上下文对它没有做任何事情的对象一无所知用它。

在Projects表类上使用Attach方法或者btw不起作用,它会引发异常。

回答

3

你应该看看迈克哈德洛的(新BSD)实施SutekiShop

在那里你会发现一个DataBindAttribute和BindUsingAttribute,如果我理解正确,你就可以做你想做的事情。请注意DataBindAttribute.Fetch属性是如何用来重新绑定传入数据的,或者不是(从HttpPost)重新绑定到LINQ实体。

我使用ASP.NET MVC和LINQ-To-SQL对这个模式进行了跟踪。它的作品非常漂亮。

这里的源:http://www.google.com/codesearch?hl=en&lr=&q=DataBind+package%3Ahttp%3A%2F%2Fsutekishop.googlecode.com&sbtn=Search

+0

就是这样,谢谢罗伯特! – Kieron 2009-08-19 07:44:18

+0

SutekiShop有很多优秀的代码,很高兴它为你工作。 – 2009-08-19 13:55:55

0

我认为您传递给该方法的项目是您想要执行UpdateModel的项目,不是吗?

否则,您尝试使用预先存在的值更新而不是新的值。

只是一个想法,

代码切出以下

[AcceptVerbs (HttpVerbs.Post)] 
public ActionResult Edit (Project project) 

    UpdateModel<Project> (project); 

    if (!ModelState.IsValid) 
      return View (project); 

    var projectService = Factory.GetService<IProjectService>(); 

    project = projectService.SaveProject (project); 

    return RedirectToAction ("Details", new { id = project.ProjectId }); 
} 
+0

项目,而不是projectToUpdate是使用ModelBinder的 – 2009-08-14 13:38:27

+0

的问题,我不解释很好的一个,就是那个来自粘合剂项目实例是一切都很好,除了从它由MVC FW构建的事实来看,并没有从DataContext中检索。更新该实例时,DataContext基本上什么也不做,可能是因为它对该对象一无所知。 – Kieron 2009-08-14 13:51:50

0

你需要为你做的,然后与已经在项目更改的属性来更新它恢复原始项目更新然后提交更新请求。

编辑

试试这个代码,我发现:

public static void CloneProperties(this object origin, ref object destination) 
{ 
    if (destination == null) throw new ArgumentNullException("destination", "Destination object must first be instantiated."); 
    foreach (var destinationProperty in destination.GetType().GetProperties()) 
    { 
     if (origin != null && destinationProperty.CanWrite) 
     { 
      origin.GetType().GetProperties().Where(x => x.CanRead && (x.Name == destinationProperty.Name && x.PropertyType == destinationProperty.PropertyType)) .ToList() .ForEach(x => destinationProperty.SetValue(destination, x.GetValue(origin, null), null)); 
     } 
    } 
} 
+0

是的,这就是我正在做的 - 我想要的可能是创建一个ModelBinder,它可以为我做到这一点......简单地说,我不必每次都在控制器中进行操作。 如果我稍后更改为另一个ORM,我将执行不需要的额外获取。我需要做的活页夹是删除/恢复原来的。有什么想法吗? – Kieron 2009-08-14 14:13:06

+0

http://msdn.microsoft.com/en-us/library/bb896248.aspx – Gregoire 2009-08-14 14:38:58

+0

@格雷戈里,我试着使用Attach方法回来,但它引发了一个关于对象的异常已经存在(我假设它检查基础就是PK)。 – Kieron 2009-08-14 14:56:20