【问题标题】:Dynamically attach entry to context将条目动态附加到上下文
【发布时间】:2014-08-11 09:03:09
【问题描述】:

我正在使用 .Net 4.5 和 Entity Framework 6 创建一个 REST Web API。 在我的更新方法中,我需要将在 web api 中收到的对象附加回 dbcontext。我已经使用下面的代码实现了这一点。我现在要做的是使这段代码可重用,以便我可以为模型中的任何对象调用 AttachToContext。

我知道我必须使用泛型类型 T 和 TEntity,但我找不到任何合适的示例。

//Repository.cs
public void UpdateOrderItem(OrderItem orderItem)
            {
                try
                {
                    AttachToContext(orderItem);
                    _context.SaveChanges();
                }
                catch (Exception e)
                {
                }
            }

            private void AttachToContext(OrderItem orderItem)
            {
                var entry = _context.Entry<OrderItem>(orderItem);
                if (entry.State == EntityState.Detached)
                {
                    var attachedEntity = FindExistingEntity(orderItem.Id);
                    if (EntityExists(attachedEntity))
                    {
                        UpdateEntityValues(attachedEntity, orderItem);
                    }
                    else
                    {
                        entry.State = EntityState.Modified;
                    }
                }

            }

            private OrderItem FindExistingEntity(int id)
            {
                var set = _context.Set<OrderItem>();
                return set.Find(id);
            }

            private void UpdateEntityValues(OrderItem existing, OrderItem updated)
            {
                var attachedEntry = _context.Entry(existing);
                attachedEntry.CurrentValues.SetValues(updated);
            }

            private bool EntityExists(object entity)
            {
                return entity != null;
            }

【问题讨论】:

    标签: asp.net entity-framework-6 dbcontext


    【解决方案1】:

    您的 AttachToContext 依赖于主键属性 orderItem.Id,要将其更改为动态的,您可以引入一个接口并为您拥有的所有实体实现或仅将 id 作为参数传递。

    界面

    public interface IEntity
    {
        public int Id { get; set; }
    }
    public class OrderItem : IEntity
    {
        // body
    }
    

    然后修改AttachToContext如下。

    private void AttachToContext<T>(T entity) where T : class, IEntity
    {
        var entry = _context.Entry(entity);
        if (entry.State == EntityState.Detached)
        {
            var attachedEntity = FindExistingEntity<T>(entity.Id);
            if (EntityExists(attachedEntity))
            {
                UpdateEntityValues(attachedEntity, entity);
            }
            else
            {
                entry.State = EntityState.Modified;
            }
        }
    }
    private T FindExistingEntity<T>(int id) where T : class
    {
        var set = _context.Set<T>();
        return set.Find(id);
    }
    private void UpdateEntityValues<T>(T existing, T updated) where T : class
    {
        var attachedEntry = _context.Entry(existing);
        attachedEntry.CurrentValues.SetValues(updated);
    }
    

    用法是AttachToContext(orderItem);

    传递密钥

    private void AttachToContext<T>(T entity, params object[] id) where T : class
    {
        var entry = _context.Entry(entity);
        if (entry.State == EntityState.Detached)
        {
            var attachedEntity = FindExistingEntity<T>(id);
            if (EntityExists(attachedEntity))
            {
                UpdateEntityValues(attachedEntity, entity);
            }
            else
            {
                entry.State = EntityState.Modified;
            }
        }
    }
    private T FindExistingEntity<T>(object[] id) where T : class
    {
        var set = _context.Set<T>();
        return set.Find(id);
    }
    private void UpdateEntityValues<T>(T existing, T updated) where T : class
    {
        var attachedEntry = _context.Entry(existing);
        attachedEntry.CurrentValues.SetValues(updated);
    }
    

    用法是AttachToContext(orderItem, orderItem.Id);

    另一种选择是使用对象集来获取主键属性,然后使用反射来获取值。获取主键属性在this post中已经说明。

    【讨论】:

      猜你喜欢
      • 2018-12-22
      • 2013-03-26
      • 2013-01-09
      • 2012-08-21
      • 2011-04-07
      • 1970-01-01
      • 1970-01-01
      • 2017-08-19
      • 2011-04-07
      相关资源
      最近更新 更多