0

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

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”等,尤其是因为所有这些文件都有里面的代码完全相同。

有什么建议吗?

谢谢。

4

2 回答 2

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);
    }
}
于 2013-08-09T14:49:40.543 回答
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;
        }
    }
于 2013-08-08T23:40:49.850 回答