简体   繁体   English

如何使用Entity Framework处理数据库事务跟踪

[英]How to deal with database transaction tracking with Entity Framework

For an ASP.NET MVC application that I'm developing, my entities are going against pre-existing tables that have columns designed to track database transactions (LastModDate, LastModByUserId, CreateDate,CreateByUserId), but aren't set up with triggers of their own to automatically populate these columns. 对于我正在开发的ASP.NET MVC应用程序,我的实体将与已存在的表相对应,这些表具有旨在跟踪数据库事务的列(LastModDate,LastModByUserId,CreateDate,CreateByUserId),但未设置其触发器拥有以自动填充这些列。 I'm a bit out of my comfort zone as in the past I've only worked with tables that either have these columns populated via database triggers or have transaction tracking done manually but in a separate table (usually something I've seen in dealing with ESBs and ordering systems). 我有点不适应,因为过去我只使用那些通过数据库触发器填充这些列或手动完成事务跟踪但在单独的表中的表(通常是在处理表时见过的表) ESB和订购系统)。

My assumption for why these columns are set up this way is to override fields relating to who the user is, in scenarios where the user is authenticated but the web application connection to the database is done through an application user account. 我对为什么要以这种方式设置这些列的假设是,在对用户进行身份验证但通过应用程序用户帐户完成Web应用程序与数据库的连接的情况下,覆盖与用户身份有关的字段。

So my question is in designing Models that map to these tables do I just extend a "DBEntity" type class and call an "Update/Updated" routine prior to doing any modifications? 所以我的问题是在设计映射到这些表的模型时,我是否只是在进行任何修改之前扩展“ DBEntity”类型类并调用“ Update / Updated”例程? Also, is having these type of manually populated transaction columns common? 此外,使用这些类型的手动填充的交易列是否常见? Thanks. 谢谢。

public class DBEntity
{
    //Primary Key
    public int Id { get; set; }
    public DateTime LastModDate {get; set;}
    public int LastModByUserId {get; set;} 
    public DateTime CreateDate {get; set;}
    public int CreateByUserId {get; set;}

    public DBEntity(UserLogin currentUser)
    {
        CreatedDate=DateTime.Now;
        CreatedByUserId=currentUser.Id;
        Updated (UserLogin);
    }
    public void Updated (UserLogin user)
    {
        LastModDate =DateTime.Now;
        LastModUserId =user.Id;
    }
}
public class UserLogin : DBEntity
{        
    public string Name { get; set; }
    public string UserName { get; set; }
    public string UserPassword { get; set; }
}

You could make the property set methods protected/private and do a similar thing MVC uses with html helpers. 您可以将属性设置方法设置为保护/私有,并在MVC与html帮助器之间进行类似的操作。

So you would end up with something like: 因此,您最终将得到以下结果:

someEntity.Update( x => x.Property, propertyValue, user);

If you are confused I can post the Update method declaration. 如果您感到困惑,我可以发布Update方法声明。

I am not sure about whether this scenario is common but I certainly think it would be a better idea to implement that as database triggers. 我不确定这种情况是否常见,但是我当然认为将其作为数据库触发器来实现是一个更好的主意。 But if you must do it manually I think this is the best you can do to automate the process. 但是,如果您必须手动执行此操作,我认为这是使流程自动化的最佳方法。

EDIT: 编辑:

Here you go 干得好

public class DBEntity
{
    public short Prop1 { get; protected set; }
    public string Prop2 { get; protected set; }

    public DBEntity()
    {
    }

    public void Update<T>( Expression<Func<DBEntity, T>> outExpr, T value)
    {
        if (value != null)
        {
            var expr = (MemberExpression)outExpr.Body;
            var prop = (PropertyInfo)expr.Member;
            prop.SetValue(this, value, null);
        }
    }

}

Test: 测试:

static void Main(string[] args)
{
    DBEntity e = new DBEntity();
    e.Update<string>(x => x.Prop2, "test");
    Console.WriteLine(e.Prop2);
}

Leave me a comment if you still have any questions. 如果您还有任何问题,请给我评论。 Good luck! 祝好运!

You could look into overriding the DbContext.SaveChanges() method to update your create/update tracking fields ( ObjectContext has a SavingChanges event if you are using that instead of DbContext ). 您可以研究重写DbContext.SaveChanges()方法以更新您的创建/更新跟踪字段(如果使用ObjectContext而不是DbContext ,则ObjectContext具有SavingChanges事件)。

You would probably want to create an interface for the fields, and then in SaveChanges() you could use the ChangeTracker to find the added and modified entities, and if they implement your interface, cast and update the properties. 您可能想为这些字段创建一个接口,然后在SaveChanges()使用ChangeTracker查找添加和修改的实体,如果它们实现了您的接口,则ChangeTracker转换和更新属性。

This answer has some code that does something similar. 这个答案有一些类似的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM