我正在一个网站上工作,解决方案中有两个项目是业务逻辑项目和网站项目。我知道我希望将实体上下文保留在Web项目之外,并且只使用框架创建的业务对象,但我无法弄清楚如何以这种方式保存修改后的对象。
假设我的实体模型创建了这个类:
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代码指出我正确的方向;链接到一个帖子解释如何处理这类事情也会起作用。
2)有人可以为保存方法提供一些psudo代码吗?如果附加或删除了地址,save方法也需要处理。
答案 0 :(得分:2)
有很多方法可以将Entity Framework作为持久层处理。
首先,看起来你没有使用纯POCO。也就是说,让EF为您生成类(在EDMX.designer.cs文件中)。
没有错,但它确实会抑制问题的清晰分离(特别是在单元测试方面)。
您是否考虑过实施Repository模式来封装您的EF逻辑?这将是一种从UI中隔离逻辑的好方法。
就保存而言 - 这是困难的地方。你是对的,大多数人都使用部分课程。通常,您将拥有一个公开虚拟“保存”方法的基类,然后可以覆盖部分类。
我个人不喜欢这种模式 - 我相信POCO不应该关心持久性或底层基础设施。因此,我喜欢使用纯POCO(无代码),存储库模式和工作单元。
工作单元为您处理上下文打开/保存/关闭。
这就是(我的)工作单位如何发挥魔力。考虑一下“Web”项目中的一些代码:
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行保存对数据上下文的更改,并关闭上下文。
现在,这些模式还有很多,所以我建议你阅读这些模式,看它是否适合你。
我的存储库也使用Generics实现,因此我可以将此接口重用于所有业务实体持久性。
另请查看我在Stack Overflow上提出的其他一些问题 - 您可以看到我是如何实现这些模式的。
不确定这是否是您正在寻找的“答案”,但我想我会给您一些替代选择。