在我阅读附加链接中的一个问题之后,我了解了如何在Entity Framework中设置DateCreated和DateModified列并在我的应用程序中使用它.但是,在旧的sql方式中,触发方式更受欢迎,因为从DBA的角度来看更安全.
那么关于哪种方式的建议是最佳做法?是否应该在实体框架中设置应用程序完整性?或者应该使用触发器,因为从数据安全的角度来看它更有意义吗?或者有没有办法在实体框架中组合触发器?谢谢.
EF CodeFirst: Rails-style created and modified columns
顺便说一下,即使它并不重要,我正在使用ASP.NET MVC C#构建这个应用程序.
解决方法
意见:触发器就像隐藏的行为,除非你去寻找它们,否则你通常不会意识到它们在那里.我也喜欢在使用EF时尽可能保持DB“哑”,因为我使用的是EF,所以我的团队不需要维护sql代码.
对于我的解决方案(在另一个同时包含DataContext的项目中,将ASP.NET WebForms和MVC在C#中与Business Logic混合使用):
我最近有一个类似的问题,虽然对于我的情况它更复杂(DatabaseFirst,所以需要一个自定义的TT文件),解决方案大致是相同的.
我创建了一个界面:
public interface ITrackableEntity { DateTime CreatedDateTime { get; set; } int CreatedUserID { get; set; } DateTime ModifiedDateTime { get; set; } int ModifiedUserID { get; set; } }
然后我就在我需要的任何实体上实现了该接口(因为我的解决方案是DatabaseFirst,我更新了TT文件以检查表是否有这四列,如果是这样,则将接口添加到输出).
更新:这是我对TT文件的更改,我更新了EntityClassopening()方法:
public string EntityClassopening(EntityType entity) { var trackableEntityPropNames = new string[] { "CreatedUserID","CreatedDateTime","ModifiedUserID","ModifiedDateTime" }; var propNames = entity.Properties.Select(p => p.Name); var isTrackable = trackableEntityPropNames.All(s => propNames.Contains(s)); var inherits = new List<string>(); if (!String.IsNullOrEmpty(_typeMapper.GetTypeName(entity.BaseType))) { inherits.Add(_typeMapper.GetTypeName(entity.BaseType)); } if (isTrackable) { inherits.Add("ITrackableEntity"); } return string.Format( CultureInfo.InvariantCulture,"{0} {1}partial class {2}{3}",Accessibility.ForType(entity),_code.SpaceAfter(_code.AbstractOption(entity)),_code.Escape(entity),_code.StringBefore(" : ",String.Join(",",inherits))); }
唯一剩下的就是将以下内容添加到我的部分DataContext类中:
public override int SaveChanges() { // fix trackable entities var trackables = ChangeTracker.Entries<ITrackableEntity>(); if (trackables != null) { // added foreach (var item in trackables.Where(t => t.State == EntityState.Added)) { item.Entity.CreatedDateTime = System.DateTime.Now; item.Entity.CreatedUserID = _userID; item.Entity.ModifiedDateTime = System.DateTime.Now; item.Entity.ModifiedUserID = _userID; } // modified foreach (var item in trackables.Where(t => t.State == EntityState.Modified)) { item.Entity.ModifiedDateTime = System.DateTime.Now; item.Entity.ModifiedUserID = _userID; } } return base.SaveChanges(); }
请注意,每次创建DataContext类时,我都会将当前用户ID保存在私有字段中.