2010-10-08 47 views
1

我正在网站上工作,解决方案中有两个项目是业务逻辑项目和网站项目。我知道我想将实体上下文保留在Web项目之外,只使用框架创建的业务对象,但我无法弄清楚如何以这种方式保存修改后的对象。ASP.NET EntityFramework 4数据上下文问题

比方说,我的实体模型创建这个类:

public class Person //Person entity 
{ 
    Int32 Id {get;set;} 
    String Name {get;set;} 
    Address Address {get;set;} //Address entity 
} 

,我创建了这个类来获得一个特定的人:

public static class PersonController 
{ 
    public static Person GetById(int id) 
    { 
     using (Entities context = new Entities()) 
     { 
      return context.Persons.FirstOrDefault(x => x.Id == id); 
     } 
    } 
} 

这让我通过打电话来想一个人没有上下文PersonController.GetById(1);我可以在获取它们后更改人员属性,但我无法弄清楚如何将修改后的信息保存回数据库。理想情况下,我想部分类Person,并添加一个.Save()方法,该方法将处理创建一个上下文并将其添加到其中并保存更改。但是当我前一阵子尝试时,它仍然存在各种各样的问题,它仍旧附加到旧的上下文中,即使我将它解锁并将它附加到一个新的上下文,它将作为EntityState.Unchanged被附加,如果我没有记错,那么当我在附加它后调用context.SaveChages()时,实际上没有任何更新。

我想我有两个问题:

1)我要对这个的一个好办法/有没有更好的办法?如果我以一种非常可怕的方式来做这件事,我会很感激一些psudo-code让我指出正确的方向;一个解释如何去做这种事情的帖子的链接也会起作用。

2)有人可以提供一些保存方法的psudo代码?如果地址被附加或删除,save方法也需要处理。

回答

1

有许多方法可以将实体框架作为持久层处理。

首先,它看起来像你不使用纯POCO的。也就是说,您让EF为您生成类(在EDMX.designer.cs文件中)。

这没有错,但它确实抑制了一个清晰的关注点(特别是在单元测试时)。

您是否考虑实施Repository模式来封装您的EF逻辑?这将是从您的用户界面中分离逻辑的好方法。

在保存方面 - 这是困难的地方。你是对的,大多数人使用部分班。通常,您将拥有一个基类,它公开了一个虚拟的“保存”方法,然后这些分类可以覆盖。

我个人不喜欢这种模式 - 我相信POCO不应该关心持久性或底层基础设施。因此,我喜欢使用纯粹的POCO(无代码代码),存储库模式和工作单元。

工作单元处理您打开/保存/关闭的上下文。

这就是(我的)工作单元如何做到这一点。考虑此部分代码在您的“网络”项目:

var uOw = new UnitOfWork(); // this is class i created, implementing the UOW pattern 
var person = repository.Find(10); // find's a "Person" entity (pure POCO), with id 10. 
person.Name = "Scott"; 
uOw.Commit(); 

或添加新联系人:

var uOw = new UnitOfWork(); 
var newPerson = new Person { Name = "Bob" }; 
repository.Add(newPerson); 
uOw.Commit(); 

真好是什么? :)

第1行为您创建一个新的sql上下文。 第2行使用相同的上下文来检索单个“Person”对象,该对象是手动编码的POCO(不是由EF生成的)。 第3行更改Person(纯POCO setter)的名称。 第4行保存对数据上下文的更改,并关闭上下文。

现在,这些模式比这个更多,所以我建议你阅读这些模式,看看它是否适合你。

我的存储库也使用泛型实现,所以我可以重新使用此接口来实现所有业务实体持久性。

另请参阅我在StackOverflow上询问的其他一些问题 - 您可以看到我是如何实现这些模式的。

不知道这是您寻找的“答案”,但我想我会给你一些替代选择。

希望这会有所帮助。

+0

我是一个漂亮的新开发者,所以我没有很多设计模式的经验。因此我不知道如何使用存储库模式,但我可以查看。为什么你不想使用EF生成的对象呢?我认为EF的重点在于它能够自动生成对象,并且可以为您节省时间编码;这两方面你都不需要编写代码,而且你没有测试你不写的代码。 – William 2010-10-09 19:04:24

+0

那么有太多的原因,太多不能进入这里。主要的是可扩展性。如果你让EF生成你的类,这些类与EF绑定,并且是数据库感知的。他们需要知道他们如何被使用(映射)。有了POCO,他们不知道。因此,您可以将EF转换为nHibernate(例如),而无需额外更改代码。此外,您的课程现在纯粹代表您的领域模型 - 它们不会与导航属性和事件代表混杂在一起。对于简单的应用程序(不会长期存在的),EF gen很好。 – RPM1984 2010-10-09 22:30:57

+0

RE测试 - 您不直接测试类,但例如如果您有服务层(大多数应用程序都是这样),则需要确保您可以创建/检索/删除实体。通过使用code-gen,测试服务层时需要参考实体框架。这不应该被要求。你最终得到的是所有项目引用实体框架 - 因此你放弃了“松耦合”。 – RPM1984 2010-10-09 22:32:49