Alter SaveChanges when Seeding database

时间:2015-10-06 08:50:59

标签: c# asp.net entity-framework autofac

I have a setup where I use a service to log a user in and autofill the CreatedBy, UpdatedBy, ... fields for my entities. Because of this my SaveChanges method looks like this:

public override int SaveChanges()
{
    var modifiedEntries = ChangeTracker.Entries()
        .Where(x => x.Entity is IAuditableEntity
                        && (x.State == EntityState.Added || x.State == EntityState.Modified));

    var activeUserId = ActiveUserService.UserId;
    var username = Users.First(x => x.Id == activeUserId).UserName;

    foreach (var entry in modifiedEntries)
    {
        IAuditableEntity entity = entry.Entity as IAuditableEntity;

        if (String.IsNullOrEmpty(username))
        {
            throw new AuthenticationException(
                "Trying to save entities of type IAuditable while not logged in. Use the IActiveUserService to set a logged in user");
        }

        if (entity != null)
        {
            DateTime now = DateTime.Now;

            if (entry.State == EntityState.Added)
            {
                entity.CreatedBy = username;
                entity.CreatedAt = now;
            }
            else
            {
                base.Entry(entity).Property(x => x.CreatedBy).IsModified = false;
                base.Entry(entity).Property(x => x.CreatedAt).IsModified = false;
            }

            entity.UpdatedBy = username;
            entity.UpdatedAt = now;
        }
    }

    return base.SaveChanges();
}

The problem is when I'm seeding my database, Autofac isn't running and isn't injecting my services. Is it possible somewhere set a flag of some sort that when I'm seeding my database I use a default username or something?

2 个答案:

答案 0 :(得分:1)

在您的代码中,如果没有用户登录(因此没有activeUserId),则会因First()上的例外而中断:

var username = Users.First(x => x.Id == activeUserId).UserName;

所以这一行:

if (String.IsNullOrEmpty(username))

永远不会成真。

我会在方法中使用一个可以为null的变量:SaveChanges(int? activeUserId = null),当你的Seed-method调用它时它将为null,你可以处理它以将用户名设置为SYSTEM。但是对于你所有的其他代码,你可以提供用户的id,并处理它。

编辑:摘要:方法本身不应检查用户是否已登录,在其他地方执行此操作。

答案 1 :(得分:0)

我目前的解决方法是在为设置默认用户的数据库播种时创建其他SaveChanges方法。

internal int SaveChangesWithDefaultUser()
{
    var modifiedEntries = ChangeTracker.Entries()
        .Where(x => x.Entity is IAuditableEntity
                    && (x.State == EntityState.Added || x.State == EntityState.Modified));

    var username = "SYSTEM";

    foreach (var entry in modifiedEntries)
    {
        IAuditableEntity entity = entry.Entity as IAuditableEntity;

        if (entity != null)
        {
            DateTime now = DateTime.Now;

            if (entry.State == EntityState.Added)
            {
                entity.CreatedBy = username;
                entity.CreatedAt = now;
            }
            else
            {
                base.Entry(entity).Property(x => x.CreatedBy).IsModified = false;
                base.Entry(entity).Property(x => x.CreatedAt).IsModified = false;
            }

            entity.UpdatedBy = username;
            entity.UpdatedAt = now;
        }
    }

    return base.SaveChanges();
}