【问题标题】:What's the most efficient way to inject behavior into all my entities?将行为注入所有实体的最有效方法是什么?
【发布时间】:2011-05-12 05:44:03
【问题描述】:

我正在将大型数据模型从旧的 Microsoft 数据访问库转换为 Entity Framework 4。我想将这两种方法“注入”到大多数(如果不是全部)从现有数据库到我的 EF 模型中:

    public bool Deleted
    {
        get { return this.EntityState == System.Data.EntityState.Deleted; }
        set 
        {
            if (value)
                Context.DeleteObject(this);
        }
    }

    public bool Inserted
    {
        get { return this.EntityState == System.Data.EntityState.Added; }
        set
        {
            if (value)
                Context.AddObject(this.GetType().Name, this);
        }
    }

除了为每个实体(超过 100 个)创建部分类之外,将这些方法添加到模型中的所有实体的更好方法是什么?

提前感谢您的建议。

【问题讨论】:

  • 添加到通用实体基类?
  • @Mitch,感谢您的建议。我已经尝试为 EntityObject 添加部分类,但显然 EntityObject 没有看到 EntityState 属性。

标签: c# entity-framework-4 extension-methods


【解决方案1】:

我会修改 EF T4 模板以自动生成这些属性。

【讨论】:

    【解决方案2】:

    扩展@Daz(有点稀疏)的答案:右键单击设计器并选择Add Code Generation Item...,然后选择ADO.NET Entity Object Generator. 它将创建一个模板,该模板生成的代码与编译器已经创建的代码完全相同,然后您可以定制。打开它,很容易看到如何修改它。它专为您描述的目的而设计。

    Here's a recent MSDN article详细描述事物。

    【讨论】:

    • @Daz,感谢您的建议。我希望在代码生成器之外做到这一点。我在想可以开发一个方面或扩展方法来将此行为添加到类中。但如果没有其他解决方案,我可能会修改代码生成。
    【解决方案3】:

    为您的实体创建一个新的基类,它应该继承您正在使用的当前基类并使用该代码扩展其成员。

    【讨论】:

    • 彼得说得对。我希望这种行为在代码生成之外,或者想修改代码生成以具有这些属性。
    【解决方案4】:

    扩展方法可以解决问题。但当然它们是方法,而不是像您在示例中创建的适当属性(框架中尚不存在扩展属性,只有扩展方法)。

    public static class EntityObjectExtensions
    {
        public static bool IsDeleted(this EntityObject obj)
        {
            return obj.EntityState == System.Data.EntityState.Deleted;
        }
    
        public static bool Delete(this EntityObject obj)
        {
            Context.DeleteObject(obj);
        }
    
        public static bool IsInserted(this EntityObject obj)
        {
            return obj.EntityState == System.Data.EntityState.Added;
        }
    
        public static bool Insert(this EntityObject obj)
        {
            Context.AddObject(obj.GetType().Name, obj);
        }
    }
    

    毫无疑问,此解决方案是最优雅且最接近您需求的解决方案。无需接触代码生成,也无需在所有类上复制相同的代码。如果必须在这些方法中进行某些更改,则更改将在一个地方完成,并且您的所有类都将从中受益。

    【讨论】:

    • 感谢您的回复。我正在寻找一种让属性自动对我的所有实体可用的方法,这样我就不必修改数万行客户端代码中的每一个引用。
    • @John 这正是我从你的问题中了解到的。我的回答不能满足这个要求吗?
    • 您的解决方案创建了方法。为了尽量减少对客户端代码的更改,我正在寻找属性包装器。您提供了一个解决方案,但没有一个允许我使用现有客户端代码的解决方案。
    • 好的,我明白了。不幸的是,没有成千上万的选择。要么你对 1000 个班级进行 1000 次更改,要么你在一个精心挑选的地方进行 1 次更改。知道... 1 / 如果您通过代码生成添加属性但您不想这样做,您可以保持调用不变。 2/ 扩展只能是方法:它强制改变所有的调用,而你不想这样做。 3/ 可以将属性添加到一个共同的祖先类:您尝试向 EntityObject 添加一个部分类,但似乎您没有设法做到。呃……看起来可能不得不考虑妥协……
    • Ssithra,感谢您的努力。当然还有其他方法可以做到这一点,随着 EF 或其模板的更新,或者如果我们采用 DevForce,或者模型得到更新,或者应用程序的发展,所有这些方法都会带来麻烦。事实证明,并非所有实体都需要这些属性,所以我们只创建了我们需要的那些。此外,您上面的示例在运行时也不起作用。例如,集合的复数化会导致 Context.AddObject(obj.GetType().Name, obj) 失败,所以它不可能是泛型的。
    猜你喜欢
    • 2011-12-30
    • 2019-07-12
    • 1970-01-01
    • 2021-09-28
    • 2012-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多