0

Is there an equivalent of Rails ActiveRecord::Callbacks in ASP MVC?

http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html

I'm in a situation where we are not using identities for our primary key. We do this for reasons specific to our DB sharding design. Because of this we have a lookup table to find the next ID for a specific table. I'd like to automatically get this value and set it in an abstract class whenever a model is created/updated and before it is saved. I also need to update the lookup table with an incremented 'nextID' after the save is successful.

I'm open to other solutions on how to do this without callbacks as well.

4

2 回答 2

0

所以你需要回调来增加查找表中的 ID 吗?AFAIK 在 ASP.NET 中没有等效项,您可以尝试使用异步控制器(http://msdn.microsoft.com/en-us/library/ee728598%28v=vs.100%29.aspx)并等待成功保存后的状态更改,但我更喜欢使用专门为此服务的服务,例如 Snowflake ( https://github.com/twitter/snowflake/ )。

于 2013-02-21T22:01:48.670 回答
0

我找到了一个使用覆盖而不是回调的解决方案。我希望 ASP mvc 随着框架的不断成熟增加对回调的支持,因为回调通过允许 OnSave 事件存在于事件所关注的模型中而不是集中式 DbContext 类(分离担忧)。

解决方案:

SaveChanges 方法可以在 Context 类中被覆盖(Entity Framework Power Tools创建 Context 类是 'Models' 目录)。

    public override int SaveChanges()
    {
        // create a cache for id values in case their are multiple added entries in the dbcontext for the same entitytype
        Dictionary<string, UniqueID> idCache = new Dictionary<string, UniqueID>();
        IEnumerable<DbEntityEntry> changes = this.ChangeTracker.Entries();
        foreach (var entry in changes)
        {
            //check if this is a new row (do nothing if its only a row update because there is no id change)
            if (entry.State == System.Data.EntityState.Added)
            {
                //determine the table name and ID field (by convention)
                string tableName = entry.Entity.GetType().Name;
                string idField = entry.Entity.GetType().Name + "ID";
                UniqueID id = null;
                //if we've already looked this up, then use the cache
                if (idCache.ContainsKey(tableName))
                {
                    id = idCache[tableName];
                }
                //if we havn't looked this up before get it and add it to the cache
                else
                {
                    id = this.UniqueIDs.Find(tableName, idField);
                    //if it doesn't already exist in the lookup table create a new row
                    if (id == null)
                    {
                        id = new UniqueID(tableName, idField, 1);
                        // since this is a new entry add it
                        this.UniqueIDs.Add(id);
                    }
                    else
                    {
                        // set the state to modified
                        this.Entry(id).State = System.Data.EntityState.Modified;
                    }
                }
                entry.CurrentValues[tableName + "ID"] = id.NextID;
                id.NextID = id.NextID + 1;
            }

        }
        return base.SaveChanges();
    }
于 2013-02-25T17:04:26.763 回答