[英]Fluent NHibernate Generated Audits
I need some help setting up my Fluent NHibernate POCO class structure. 我需要一些帮助来设置Fluent NHibernate POCO类结构。 I'm trying to simply have a way to make an object auditable.
我试图简单地使对象成为可审核的方法。 On Create, I want my created and modified datetimes to be set and on update, I want my modified to be updated.
在创建时,我要设置我创建和修改的日期时间,在更新时,我要修改我的修改时间。 I've been following some examples, but I have hit a road block.
我一直在关注一些示例,但遇到了障碍。 This is my current setup:
这是我当前的设置:
IAuditable.cs IAuditable.cs
namespace ZeroBase.Domain.Entities
{
public interface IAuditable
{
DateTime Created
{
get;
}
DateTime Modified
{
get;
}
string CreatedPropertyName
{
get;
}
string ModifiedPropertyName
{
get;
}
void SetCreationDate(DateTime created);
void SetModifiedDate(DateTime modified);
}
}
AuditableEntity.cs AuditableEntity.cs
namespace ZeroBase.Domain.Entities
{
public class AuditableEntity<T> : IAuditable
{
public DateTime Created { get; private set; }
public DateTime Modified { get; private set; }
void IAuditable.SetCreationDate(DateTime created)
{
this.Created = created;
}
void IAuditable.SetModifiedDate(DateTime modified)
{
this.Modified = modified;
}
string IAuditable.CreatedPropertyName
{
get
{
string createdPropName = "Created";
#if DEBUG
CheckIfPropertyExists(createdPropName);
#endif
return createdPropName;
}
}
string IAuditable.ModifiedPropertyName
{
get
{
string modifiedPropName = "Modified";
#if DEBUG
CheckIfPropertyExists(modifiedPropName);
#endif
return modifiedPropName;
}
}
private void CheckIfPropertyExists(string propertyName)
{
PropertyInfo pi = this.GetType().GetProperty(propertyName);
Debug.Assert(pi != null, String.Format("There exists no property {0}", propertyName));
}
}
}
User.cs User.cs
namespace ZeroBase.Domain.Entities
{
public class User : AuditableEntity<User>
{
public virtual Guid Id { get; set; }
public virtual string Username { get; set; }
public virtual string Password { get; set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual string EmailAddress { get; set; }
public virtual IEnumerable<Comment> Comments { get; set; }
}
}
AuditInterceptor.cs AuditInterceptor.cs
namespace ZeroBase.Infrastructure.Data
{
public class AuditInterceptor : EmptyInterceptor
{
public override bool OnFlushDirty(object entity, object id, object[] currentState, object[] previousState,
string[] propertyNames, NHibernate.Type.IType[] types)
{
IAuditable auditableObject = entity as IAuditable;
if (auditableObject != null)
{
for (int i = 0; i < propertyNames.Length; i++)
{
if (propertyNames[i] == auditableObject.ModifiedPropertyName)
{
currentState[i] = DateTime.Now;
}
}
return true;
}
return false;
}
public override bool OnSave(object entity, object id, object[] state, string[] propertyNames, NHibernate.Type.IType[] types)
{
IAuditable auditableObject = entity as IAuditable;
if (auditableObject != null)
{
DateTime currentDate = DateTime.Now;
for (int i = 0; i < propertyNames.Length; i++)
{
if (propertyNames[i] == auditableObject.CreatedPropertyName)
{
state[i] = currentDate;
}
if (propertyNames[i] == auditableObject.ModifiedPropertyName)
{
state[i] = currentDate;
}
}
System.Diagnostics.Debug.WriteLine("interceptor: created: " + auditableObject.Created);
System.Diagnostics.Debug.WriteLine("interceptor: modified: " + auditableObject.Modified);
return true;
}
return false;
}
}
}
AuditMap.cs AuditMap.cs
namespace ZeroBase.Infrastructure.Data
{
public class AuditMap<T>: ClassMap<T> where T : AuditableEntity<T>
{
public AuditMap()
{
Map(p => p.Created);
Map(p => p.Modified);
}
}
}
UserMap.cs UserMap.cs
namespace ZeroBase.Infrastructure.Data
{
public class UserMap : AuditMap<User>
{
public UserMap()
{
Id(x => x.Id)
.Column("Id")
.GeneratedBy.Guid();
Map(x => x.Username);
Map(x => x.Password);
Map(x => x.FirstName);
Map(x => x.LastName);
Map(x => x.EmailAddress);
HasMany(x => x.Comments);
Table("Users");
}
}
}
SessionHelper.cs SessionHelper.cs
_sessionFactory = Fluently.Configure()
// Set up database connection
.Database(MsSqlConfiguration.MsSql2005
.ConnectionString(x => x.Is(_connectionString))
//.ShowSql()
)
// Use class mappings
.Mappings(m => m.FluentMappings
.AddFromAssemblyOf<UserMap>())
.ExposeConfiguration(c => c.SetInterceptor(new AuditInterceptor()))
.BuildSessionFactory();
When I try to run this, I get this runtime error: The following types may not be used as proxies: ZeroBase.Domain.Entities.User: method get_Created should be 'public/protected virtual' or 'protected internal virtual' ZeroBase.Domain.Entities.User: method get_Modified should be 'public/protected virtual' or 'protected internal virtual'"} 当我尝试运行此脚本时,出现此运行时错误:下列类型可能不用作代理:ZeroBase.Domain.Entities.User:方法get_Created应该是“公共/受保护的虚拟”或“受保护的内部虚拟” ZeroBase.Domain .Entities.User:方法get_Modified应该是“公共/受保护的虚拟”或“受保护的内部虚拟”“}
What is this trying to tell me? 这是想告诉我什么?
Does this have anything to do with Fluent NHibernate? 这与Fluent NHibernate有关系吗?
I'm a little confused and would love some help! 我有些困惑,很想帮忙!
Created
and Modified
properties in your AuditableEntity<T>
class need to be virtual. AuditableEntity<T>
类中的Created
和Modified
属性需要是虚拟的。 This is a requirement of NHibernate, if you are using lazy loading (on by default). 如果您正在使用延迟加载(默认情况下启用),则这是NHibernate的要求 。
Also, there are some questions about it here on SO. 此外,还有一些 问题, 关于它在这里SO。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.