共享基类的EF代码优先配置 - >单个配置文件

时间:2013-08-08 23:26:57

标签: c# entity-framework entity-framework-5 code-first ef-migrations

我在C#项目中使用EF 5.0 Code First。我有一个基本的clase,我的大多数域模型都来自于它。

public abstract class AuditableModelBase
{
    public Int32 CreatedByUserId { get; set; }

    public DateTime CreatedDate { get; set; }

    public virtual UserProfile CreatedByUserProfile { get; set; }

    public Int32 UpdatedByUserId { get; set; }

    public DateTime UpdatedDate { get; set; }

    public virtual UserProfile UpdatedByUserProfile { get; set; }

    public AuditableModelBase()
    {
        CreatedByUserId = 1;
        CreatedDate = DateTime.UtcNow;
        UpdatedByUserId = 1;
        UpdatedDate = DateTime.UtcNow;
    }
}

但是,对于每个实体,我必须定义特定配置以将这些关系连接在一起。

// Relationships
        this.HasRequired(amb => amb.CreatedByUserProfile).WithMany().HasForeignKey(amb => amb.CreatedByUserId).WillCascadeOnDelete(false);
        this.HasRequired(amb => amb.UpdatedByUserProfile).WithMany().HasForeignKey(amb => amb.UpdatedByUserId).WillCascadeOnDelete(false);

我正在寻找一种方法来为一个抽象基类声明一个类似于上面的配置,而不必为我的每个实体创建一个单独的配置文件。我希望只有一个名为“AuditableModelBaseMap.cs”的文件,它将具有我的配置,而不是“Entity1Map.cs”,“Entity2Map.cs”,“Entity3Map.cs”等,特别是因为所有这些文件都具有完全相同的代码。

有什么建议吗?

感谢。

2 个答案:

答案 0 :(得分:0)

尝试如下,但我没有测试过。但是,如果我是你,我不会这样设计审计表

class AuditableModelBaseMap : EntityTypeConfiguration<AuditableModelBase>
    {
        public AuditableModelBaseMap ()
        {
            this.HasRequired(amb => amb.CreatedByUserProfile).WithMany().HasForeignKey(amb => amb.CreatedByUserId).WillCascadeOnDelete(false);
            this.HasRequired(amb => amb.UpdatedByUserProfile).WithMany().HasForeignKey(amb => amb.UpdatedByUserId).WillCascadeOnDelete(false);
        }
    }

这是我做审计的方式

        public interface IEntity
            {
                int Id { get; set; }
            }

         public interface IAuditable : IEntity
            {
                string UpdatedBy { get; set; }
                string CreatedBy { get; set; }
                DateTime CreatedDate { get; set; }
                DateTime UpdateDate { get; set; }
            }

    Now any entity which is auditable will implement this class your context will look the following




            public class MYContext : DbContext, ILicensingContext
            {
                private readonly IAuditLogBuilder _auditLogBuilder;


                public LicensingContext()
                    : this(new AuditLogBuilder())
                {
                }
                private IDbSet<Device> Devices { get; set; }

                private IDbSet<AuditLog> AuditLogs { get; set; }


                public MyContext(IAuditLogBuilder auditLogBuilder)
                {
                    _auditLogBuilder = auditLogBuilder;
                }



                /// <summary>
                ///     1. Constructs the AuditLog objects from the context
                ///     2. Calls SaveChanges to save the actual object modified
                ///     3. It updates the Log objects constructed in step 1 to populate the IDs returned from the Db
                ///     4. Saves the AuditLogs
                /// </summary>
                /// <returns></returns>
                public override int SaveChanges()
                {
                    var entries = ChangeTracker.Entries<IAuditable>().ToList();

                    _auditLogBuilder.UpdateAuditables(entries);
                    IEnumerable<AuditLog> auditLogEntities = _auditLogBuilder.ConstructAuditLogs(entries).ToList();


                    int countOfAffectedRecords = base.SaveChanges();

                    _auditLogBuilder.UpdateAuditLogs(auditLogEntities);
                    foreach (AuditLog auditLogEntity in auditLogEntities)
                    {
                        GetDbSet<AuditLog>().Add(auditLogEntity);
                    }
                    base.SaveChanges();
                    return countOfAffectedRecords;
                }


                public IDbSet<TEntity> GetDbSet<TEntity>() where TEntity : class
                {
                    return Set<TEntity>();
                }
            }

 public class AuditLogBuilder : IAuditLogBuilder
    {
        private string _username;

        private string Username
        {
            get
            {
                if (HttpContext.Current != null && HttpContext.Current.User != null)
                {
                    _username = HttpContext.Current.User.Identity.Name;
                }

                if (String.IsNullOrWhiteSpace(_username))
                {
                    _username = "Service Consumer";
                }
                return _username;
            }
        }

        public IEnumerable<AuditLog> ConstructAuditLogs(IEnumerable<DbEntityEntry<IAuditable>> auditableEntities)
        {
            var audits = new List<AuditLog>();
            if (auditableEntities != null)
            {
                audits.AddRange(auditableEntities
                                .Where(
                                     e =>
                                     e.State == EntityState.Modified || e.State == EntityState.Added ||
                                    e.State == EntityState.Deleted)
                           .SelectMany(GetAuditLogs));
            }
            return audits;
        }

        public void UpdateAuditLogs(IEnumerable<AuditLog> auditLogEntities)
        {
            foreach (AuditLog auditLog in auditLogEntities)
            {
                auditLog.RecordId = auditLog.Entity.Id;
                auditLog.UpdatedBy = auditLog.Entity.UpdatedBy;

                if (String.Equals(auditLog.PropertyName, "id", StringComparison.CurrentCultureIgnoreCase))
                {
                    auditLog.NewValue = auditLog.Entity.Id.ToString(CultureInfo.CurrentCulture);
                }
            }
        }

        public void UpdateAuditables(IEnumerable<DbEntityEntry<IAuditable>> entries)
        {
            if (entries != null)
            {
                foreach (var entry in entries)
                {
                    entry.Entity.UpdateDate = DateTime.UtcNow;
                    entry.Entity.UpdatedBy = Username;
                    if (entry.Entity.Id == 0)
                    {
                        entry.Entity.CreatedDate = DateTime.UtcNow;
                        entry.Entity.CreatedBy = Username;
                    }
                }
            }
        }

        private static IEnumerable<AuditLog> GetAuditLogs(DbEntityEntry<IAuditable> entry)
        {
            var audits = new List<AuditLog>();

            string entityName = ObjectContext.GetObjectType(entry.Entity.GetType()).Name;

            switch (entry.State)
            {
                case EntityState.Added:

                    audits.AddRange(entry.CurrentValues.PropertyNames.Select(propertyName =>
                                                                             new AuditLog
                                                                                 {
                                                                                     EntityName = entityName,
                                                                                     CreateDate = DateTime.UtcNow,
                                                                                     NewValue =
                                                                                         entry.CurrentValues[
                                                                                             propertyName] != null
                                                                                             ? entry.CurrentValues[
                                                                                                 propertyName].ToString()
                                                                                             : String.Empty,
                                                                                     PreviousValue = String.Empty,
                                                                                     PropertyName = propertyName,
                                                                                     Entity = entry.Entity,
                                                                                     Action = Actions.Create.ToString()
                                                                                 }));
                    break;

                case EntityState.Deleted:
                    audits.AddRange(entry.OriginalValues.PropertyNames.Select(propertyName =>
                                                                              new AuditLog
                                                                                  {
                                                                                      EntityName = entityName,
                                                                                      CreateDate = DateTime.UtcNow,
                                                                                      NewValue = String.Empty,
                                                                                      PreviousValue =
                                                                                          entry.OriginalValues[
                                                                                              propertyName] != null
                                                                                              ? entry.OriginalValues[
                                                                                                  propertyName].ToString
                                                                                                    ()
                                                                                              : String.Empty,
                                                                                      PropertyName = propertyName,
                                                                                      Entity = entry.Entity,
                                                                                      Action = Actions.Delete.ToString()
                                                                                  }));

                    break;

                case EntityState.Modified:

                    audits.AddRange(entry.OriginalValues.PropertyNames.
                                          Where(
                                              propertyName =>
                                              !Equals(entry.OriginalValues[propertyName],
                                                      entry.CurrentValues[propertyName]))
                                         .Select(propertyName =>
                                                 new AuditLog
                                                     {
                                                         EntityName = entityName,
                                                         CreateDate = DateTime.UtcNow,
                                                         NewValue =
                                                             entry.CurrentValues[propertyName] != null
                                                                 ? entry.CurrentValues[propertyName].ToString()
                                                                 : String.Empty,
                                                         PreviousValue =
                                                             entry.OriginalValues[propertyName] != null
                                                                 ? entry.OriginalValues[propertyName].ToString()
                                                                 : String.Empty,
                                                         PropertyName = propertyName,
                                                         Entity = entry.Entity,
                                                         Action = Actions.Update.ToString()
                                                     }));
                    break;
            }
            return audits;
        }
    }

答案 1 :(得分:0)

你试过这个吗?

public class AuditableModelBaseMap : EntityTypeConfiguration<AuditableModelBase>
{
    public AuditableModelBaseMap()
    {
        this.HasRequired(amb => amb.CreatedByUserProfile).WithMany().HasForeignKey(amb => amb.CreatedByUserId).WillCascadeOnDelete(false);
        this.HasRequired(amb => amb.UpdatedByUserProfile).WithMany().HasForeignKey(amb => amb.UpdatedByUserId).WillCascadeOnDelete(false);
    }
}