自定义实体框架4.1代码优先模板

时间:2012-04-30 06:30:30

标签: c# entity-framework templates ef-code-first code-first

我自己不喜欢带有大量代码的SO问题,但我将其包含在此处,因为这个问题是关于代码生成策略而不是故障排除。

我已经从我自己的代码生成器切换到EF,并且遇到了生成的实体与ObjectContext紧密绑定的问题。使用代码第一种方法似乎可以为您提供更多的杠杆作用,因为您可以像普通的POCO类一样抛出实体对象而不需要EF拥有牛。

来自代码生成背景,我定制了T4模板,为我的代码所期望的实体类添加了一些标准实现。以下是一个例子:

`

public partial class Action:
    Task,
    CloudTech.ATS.Library.Interfaces.ICloneable<CloudTech.ATS.Templates.Action>,
    CloudTech.ATS.Library.Interfaces.IPersistXml<CloudTech.ATS.Templates.Action>
{
    #region Constructors, Destructor and Initializers.

    //====================================================================================================
    // Constructors, Destructor and Initializers.
    //====================================================================================================

    public Action ()
    {
        this.InitializeData();
    }

    public void InitializeData ()
    {
        // Native Types.
        this.TemplateId = default(int);

        // Complex Types.

        // Foreign Keys.
        this.Template = new CloudTech.ATS.Templates.Template();

        // Child Objects.
        this.ActionParameters = new System.Collections.Generic.List<CloudTech.ATS.Templates.ActionParameter>();
    }

    #endregion Constructors, Destructor and Initializers.

    #region Interface Implementation: CloudTech.ATS.Library.Interfaces.ICloneable<T>.

    //====================================================================================================
    // Interface Implementation: CloudTech.ATS.Library.Interfaces.ICloneable<T>.
    //====================================================================================================

    public CloudTech.ATS.Templates.Action Clone ()
    {
        return (new CloudTech.ATS.Templates.Action().CopyFrom(this));
    }

    public CloudTech.ATS.Templates.Action CopyFrom (CloudTech.ATS.Templates.Action source)
    {
        this.InitializeData();

        // Native Types.
        this.TemplateId = source.TemplateId;

        // Complex Types.

        // Foreign Keys.
        this.Template.CopyFrom(source.Template);

        // Child Objects disabled for XML.
        //this.ActionParameters.CopyFrom(source.ActionParameters);

        return (this);
    }

    public CloudTech.ATS.Templates.Action CopyTo (CloudTech.ATS.Templates.Action destination)
    {
        return (destination.CopyFrom(this));
    }

    #endregion Interface Implementation: CloudTech.ATS.Library.Interfaces.ICloneable<T>.

    #region Interface Implementation: CloudTech.ATS.Library.Interfaces.IPersistXml<T>.

    //====================================================================================================
    // Interface Implementation: CloudTech.ATS.Library.Interfaces.IPersistXml<T>.
    //====================================================================================================

    public System.Xml.XmlElement ToXmlElement (System.Xml.XmlDocument document)
    {
        System.Xml.XmlElement element = null;

        element = document.CreateElement(this.GetType().Name);

        // Native Types.
        try { element.Attributes.Append(document, "TemplateId", this.TemplateId.ToString()); }
        catch { element.Attributes.Append(document, "TemplateId", ""); }

        // Complex Types.

        // Foreign Keys.
        element.AppendChild(this.Template.ToXmlElement(document));

        // Child Objects commented for XML.
        //element.AppendChild(this.ActionParameters.ToXmlElement(document));

        return (element);
    }

    public bool FromXmlElement (System.Xml.XmlElement element)
    {
        bool result = true;

        this.InitializeData();

        // Native Types.
        try { this.TemplateId = int.Parse(element.Attributes ["TemplateId"].Value); }
        catch { result = false; }

        // Complex Types.

        // Foreign Keys.
        this.Template.FromXmlElement(element ["Template"]);

        // Child Objects.
        //this.ActionParameters.FromXmlElement(element ["ActionParameters"]);

        return (result);
    }

    #endregion Interface Implementation: CloudTech.ATS.Library.Interfaces.IPersistXml<T>.
}

`

以上是除了EF CF生成的标准实体声明之外的所有生成代码。

我现在正在寻找一种方法来以某种方式更改构造函数,以便我自己的自定义类可以声明一个无参数的构造函数,而不是与生成的构造函数冲突。我宁愿不必使用工厂方法,因为Initialize()和InitializeData()是我们的一个非常古老的约定。

1 个答案:

答案 0 :(得分:1)

  

我现在正在寻找一种方法来改变构造函数   我自己的自定义类可以声明一个无参数的构造函数   而不是与生成的那个发生冲突。

目前尚不清楚你是什么意思。如果您将默认构造函数添加到自动生成的类中,则表示您已完成 - 您无法对其执行任何其他操作。如果不将它添加到类生成器,则可以创建Action类的第二个部分部分和默认构造函数。如果您希望生成器创建默认构造函数,并且同时想要“修改”构造函数为每个实体类型初始化的内容,则可以创建构造函数调用的部分方法。

public partial class Action
{
    public Action()
    {
        Initialize();
    }

    partial void Initialize();
}

现在您可以声明Action类的第二个部分部分,并且可以实现新部分Initialize方法:

public partial class Action
{
    partial void Initialize()
    {
        // Do something
    }
}

如果你没有实现部分方法编译器,只需从构造函数中删除对Initialize的调用,它仍然可以工作。