我正在使用asp.net MVC 3应用程序,我正在使用codeFirst方法。我正在尝试创建历史表或用户表,我想跟踪用户修改了哪些列。如何使用EF Code First执行此操作。
我需要在DataContext.savechanges之后执行吗?
请建议。
感谢。
答案 0 :(得分:1)
DbContext有一个名为Entry<T>
的方法:
var entity = context.Items.Find(id);
entity.Name = "foobar";
var entry = context.Entry<Item>(entity);
条目的类型为DbEntityEntry<T>
,其属性为OriginalValues
和CurrentValues
。
您可能会编写一些通常会检查这些属性的内容,以查看更改内容,然后自动将新记录插入到历史记录表中。
或者使用数据库触发器。
答案 1 :(得分:0)
我不确定这是否真的是“适当”的方式,但这是它通常在sql中完成的方式:
version
。IsLatestVersion
IsLatestVersion
= false。version
,并将更改另存为新实体。答案 2 :(得分:0)
听起来像你想要一个继承自ActionFilterAttribute的过滤器。就我而言,这是我最简单的例子。这是我的模型,请注意属性决定了映射到数据库。
[Table("UserProfile")]
public class UserProfile
{
[Key, DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
}
在我的情况下,它就像下面这样简单,虽然它不是历史的:
public sealed class UsersContext : DbContext
{
public UsersContext() : base("DefaultConnection")
{
}
public DbSet<UserProfile> UserProfiles { get; set; }
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
LazyInitializer.EnsureInitialized(ref _initializer, ref isInitialized, ref initializerLock);
}
public void CheckDatabase()
{
Database.SetInitializer<YourDBContextType>(null);
using (var context = new YourDBContextType())
{
if (!context.Database.Exists())
{
((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
}
}
// Uses your connection string to build the following table.
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
}
最终结果不仅是EF代码优先,而且还允许您的视图模型使用从复杂实体派生的基元。现在,如果您有另一个,请说历史,DBContext然后我建议修改文本转换文件或为您的实体创建基类。这两种方式都允许轻松生成可以插入表中的代码,然后跟进该实体,将其克隆到历史模型中并保存。总而言之,我是数据库的粉丝,首先关注约束,触发器等,而不是框架。