如何编写实体实例方法以在Entity Framework 4.0中保持自身?

时间:2010-03-31 16:55:47

标签: c# entity-framework

我正在使用Entity Framework 4.0中的小模型。我想要一个表示实体的对象的实例方法将实体持久化到数据库。因此,而不是“外部”代码:

public static void Main(string[] args)
{
   using (EFContext ctx = new EFContext())
   {
       context.AnEntitySet.AddObject(refToTheEntityInstance);
       context.SaveChanges();

相反,我希望实体的实例能够持久存在,其中Contact是实体名称。

public ContactInstance : Contact
{
    public void Persist(List<AnotherEntity> otherEntityList)
    {
        using (EFContext ctx = new EFContext())
        {
            ...
            ctx.Contacts.AddObject(this); // DOESN'T WORK.
            ...
            ...wire up navigation property to collection of AnotherEntity...
            ctx.SaveChanges();

我做错了什么。这是一个糟糕的设计吗?在我看来,一个实体,就像面向对象设计中的任何对象一样,应该“知道”如何坚持它。

Thabks,

斯科特

1 个答案:

答案 0 :(得分:1)

从模式的角度来看,你试图引入一些人喜欢的ActiveRecord模式,有些人讨厌。因此,询问这是不是很糟糕的设计可能会很快变成宗教信仰:)

虽然说它是一种常见的模式,但不幸的是它并非由EF本身支持。

您的代码存在许多问题:

1)ContactInstance不能被视为一个联系人,这是你在EF中想要做的事情,如果你在CLR中有派生类型(即ContactInstance)它必须对应于派生类型实体模型也是。 (即我怀疑你没有的实体类型,称为ContactInstance)。我猜你有这个只是添加Persist方法。另一种方法是在一个部分类中(EF适用于部分类:

public partial class Contact
{
    public void Persist(...){}
}

2)接下来,您的代码存在一些问题,实体可能会附加到多个ObjectContexts,例如,如果您编写此代码:

Contact c = new Contact();
c.Firstname = ...;
c.Surname = ...;
c.Persist();
c.Surname = ...;
c.Persist();

它将失败 - 在第二次调用Persist()时 - 因为一个实体一次只能附加到一个上下文:

  • 第一个坚持()。将实体添加到一个上下文中。
  • 第二个Persist()将尝试将同一个实体添加到另一个上下文中。例外时间!。

解决这个问题的方法是以某种方式使用Ambient上下文,使用类似ThreadBound静态的东西,但是你必须处理各种棘手的问题。

无论如何,故事的寓意是你正在尝试使用EF,但这并不容易,你必须真正思考像ObjectContext的生命周期,像附加/分离等问题。

希望这有帮助

Alex James

前EF团队成员