Entity Framework 6.0实体自定义构造函数逻辑实现

时间:2015-08-03 18:12:07

标签: c# entity-framework-6

我正在使用EF 6.0,并希望在Model.edmx 文件生成的任何类的默认构造函数执行之后/之后添加自定义逻辑。发现在不推荐使用的EntityObject生成器版本中,每个生成的类中都有部分void OnCreated方法,可能会在部分类中被覆盖以实现我想要的,但找不到任何主题但无法弄清楚如何在不弃用方法的情况下执行此操作用法。例如,我已经生成了下一个项目的集合:

public virtual DbSet<AnswerOption> AnswerOptions { get; set; }

我自定义生成的类是AnswerOption,我需要自定义它在Model.cs文件中生成的默认构造函数:

public partial class AnswerOption
{
    public AnswerOption()
    {}
}

或者至少在我的部分类

中定义的默认构造函数调用之后执行一些代码

3 个答案:

答案 0 :(得分:1)

通过编辑Model.tt T4模板文件结束。删除了无参数构造函数生成的默认条件(对于我的情况,它是34,35,64行):

if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any())
{
}

已添加

partial void OnConstructorConpletion();

在无参数构造函数的末尾调用每个实体类的生成:

#>
public <#=code.Escape(entity)#>()
{
<#
    //default T4 logic that was processing properties
#>
    OnConstructorConpletion();
}

partial void OnConstructorConpletion();
<#

因此,T4模板生成的问题样本类的结果是:

public partial class AnswerOption
{
    public AnswerOption()
    {
        OnConstructorConpletion();
    }
}

答案 1 :(得分:1)

您的解决方案很好,但我认为我会为其他人添加一些细微的变化,从而开启了许多有用的功能。

编辑你的tt文件,使Context使用你自己的Base类,例如

<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DataContextBase {
    public <#=code.Escape(container)#>()
        : base("name=<#=container.Name#>")
    {

然后使用您使用的所有内置常用函数创建基类。我有数百个有用的函数,比如保存,撤消更改,获取有关实体的信息等事件。然后,您可以在构造函数中添加对基础虚拟OnCreated的调用,如下所示

    /// <summary>
    /// A base EntityFramework DataContext class
    /// </summary>
    public partial class DataContextBase : DbContext, IDataContext
    {
        /// <summary>
        /// Provides asynchronous locking capabilities
        /// </summary>
        protected readonly AsyncLock _databaseLock = new AsyncLock("DataContext");

        public event EventHandler Disposed;
        public event SavedChangesEventHandler SavedChanges;
        public event EntitiesChangedEventHandler EntitiesChanged;

        /// <summary>
        /// A dictionary containing all EntityFramework types and properties
        /// </summary>
        private readonly Dictionary<string, List<string>> EntityFrameworkPropertyCache;


        private ILoggingService _log;
        private IExceptionService _exception;
        private IEnumerable<object> _deletedEntities;

        private Dictionary<string, string> _schemaCache;

        /// <summary>
        /// A lock that can be awaited for co-ordinating (serialising) access to the DataContext
        /// </summary>
        public AsyncLock DatabaseLock { get { return _databaseLock; } }

        /// <summary>
        /// Gets a reference to the underlying ObjectContext
        /// </summary>
        public ObjectContext Context { get { return ((IObjectContextAdapter)this).ObjectContext; } }

        /// <summary>
        /// Gets or sets the Command Timeout
        /// </summary>
        public int? CommandTimeout
        {
            get { return Database.CommandTimeout; }
            set
            {
                Database.CommandTimeout = value;
                Context.CommandTimeout = value;
            }
        }

        /// <summary>
        /// Gets the underlying SqlConnection
        /// </summary>
        public SqlConnection SqlConnection { get { return (SqlConnection) ((EntityConnection) Context.Connection).StoreConnection; } }

        /// <summary>
        /// Checks whether we can connect
        /// </summary>
        public bool CanConnect { get { return Database.Exists(); } }

        /// <summary>
        /// Gets the Server this DataSource this instance is connected to
        /// </summary>
        public string DataSource { get { return Database.Connection.DataSource; } }

        /// <summary>
        /// Gets or sets whether the context Lazyily loads properties on access
        /// </summary>
        public bool LazyLoadingEnabled
        {
            get { return Configuration.LazyLoadingEnabled; }
            set { Configuration.LazyLoadingEnabled = value; }
        }

        /// <summary>
        /// Gets or sets whether AutoDetechChanges is Enabled
        /// </summary>
        public bool AutoDetectChangesEnabled
        {
            get { return Configuration.AutoDetectChangesEnabled; }
            set { Configuration.AutoDetectChangesEnabled = value; }
        }

        /// <summary>
        /// Gets or sets whether ValidateOnSave is Enabled
        /// </summary>

        public bool ValidateOnSaveEnabled
        {
            get { return Configuration.ValidateOnSaveEnabled; }
            set { Configuration.ValidateOnSaveEnabled = value; }
        }

        /// <summary>
        /// Gets whether this DataContext is disposed
        /// </summary>
        public bool IsDisposed { get; private set; }

        /// <summary>
        /// Gets or sets whether DataContext events are raised
        /// </summary>
        public bool NotificationsBlocked { get; set; }

        /// <summary>
        /// Gets all Entities that are Modified
        /// </summary>
        public List<object> ModifiedEntities
        {
            get { return GetObjectStateEntries(EntityState.Modified).Select(e => e.Entity).ToList(); }
        }

        /// <summary>
        /// Gets all Entities that are Modified
        /// </summary>
        public List<object> AddedEntities
        {
            get { return GetObjectStateEntries(EntityState.Added).Select(e => e.Entity).ToList(); }
        }

        /// <summary>
        /// Gets all Entities that are Modified
        /// </summary>
        public List<object> DeletedEntities
        {
            get { return GetObjectStateEntries(EntityState.Deleted).Select(e => e.Entity).ToList(); }
        }


        /*
         * Instantiation
         */

        /// <summary>
        /// Constructs a new DataContextBase  
        /// </summary>
        public DataContextBase ()
        {
            EntityFrameworkPropertyCache = Context.GetEntityPropertDictionary();

            SavedChanges += OnSavedChanges;
            AddLocalEntityChangedEventHandler();

            OnCreated();
        }

        /// <summary>
        /// Constructs a new DataContextBase for the specified configuration connection key
        /// </summary>
        /// <param name="connectionKey">The config connection key</param>
        public DataContextBase (string connectionKey)
            : base(connectionKey)
        {
            EntityFrameworkPropertyCache = Context.GetEntityPropertDictionary();

            SavedChanges += OnSavedChanges;
            AddLocalEntityChangedEventHandler();

            OnCreated();
        }


        protected virtual void OnCreated()
        {
        }
}

答案 2 :(得分:0)

DbContext有OnModelCreating,可以在初始DbContext之后但在DbContext被锁定之前使用:

https://msdn.microsoft.com/en-US/library/system.data.entity.dbcontext.onmodelcreating(v=vs.113).aspx#M:System.Data.Entity.DbContext.OnModelCreating(System.Data.Entity.DbModelBuilder)

DbSet没有等价物,但您可以在创建的模型类上创建部分类实现,这些实现是从DbSet派生的,并将您的唯一逻辑嵌入到这些类中。这些应该与Entity Framework创建的文件分开,以便在重新创建实体类时,代码不会被替换。