实体框架保存/更新的单一方法

时间:2011-09-27 20:07:00

标签: entity-framework entity-framework-4

问题是我正在尝试找到一种方法来保存实体,无论是新实体还是已经加载的实体。大多数代码示例都将Add和Save方法分开,这与使用单个Save()方法的许多其他当前设计相悖。

让我说明我已阅读其他帖子。我已经查看了关于存储库模式的团队博客,它有一个AddObject()方法,我似乎无法通过假设它只是一个Add(对象)来找到它。

如果我们加载一个对象并保存它,那么上下文就会知道它。 我们必须添加一个新对象。 如果我们添加一个现有对象 - 它将作为插入发送它。

我想要一个保存程序。用户不必知道调用添加或更新,Save()就足够了。话虽如此,对于单个保存解决方案,这是什么最好的路径,涵盖相同的方法(只有保存,而不是负载): 1.加载实体,保存回db。 2.创建新实体,将其保存到数据库。 所以我正在寻找一种在所有情况下都可以

的实现
ICustomerRepository.Save(Customer customer)

你会使用哪种解决方案?

Save(entity)方法中的以下代码似乎对我有用


//If the primary key is empty, its a new record
if (order.OrderId == 0)
{
   _context.Orders.Add(order);
}

if (_context.Entry(order).State == System.Data.EntityState.Detached)
{
   //Need to set modified so any detached entities are updated otherwise they won't be sent across to the db. Since it would've been outside the context, change tracking wouldn't have occurred anyways so we have no idea about its state - save it!
   _context.Orders.Attach(order);
   _context.Entry(order).State = System.Data.EntityState.Modified;
}


这里的问题是使用Generic Repository实现,这里没有明确的方法,没有查询键是什么,然后通过不清晰的反射检查它的值。

3 个答案:

答案 0 :(得分:2)

通用存储库是童话故事。存储库模式的唯一有效用法是特定存储库,特定存储库知道密钥的类型以及默认值。同样地,如果您的密钥不是在数据库中生成,而是在应用程序中生成,那么您可以抱怨您的通用代码不起作用。

EF对单个方法处理没有任何支持,也不能简单地添加。为了使其正常工作,您需要在SQL级别上执行条件插入/更新(或在SQL Server 2008中合并)。 EF没有这样的东西,它将两个操作分开到命令执行。

这意味着实现这一目标的唯一方法是使用您在代码示例中显示的某些“知识”,或者通过使用单独的数据库调用或使用存储过程检查数据库中实体的存在。

答案 1 :(得分:1)

public abstract class EntityObject
{
    /*Allows for this:
        T UpdateOrInsert<T>(T item) where T : EntityObject
        {
            T foundItem = depDA.Set<T>().Find(item.EntityKey);
            return foundItem;
        }
    etc


     inherit entity partials from this

     partial class MyObject : EntityObject
     {
         override int EntityKey { get { return MyObjectID; } } 
     }

    */

    public abstract int EntityKey { get; }

}

将此方法弹出到Helper类

public static T SaveEntity<T>(T item, DbContext context) where T : EntityObject
{
    T foundItem = context.Set<T>().Find(item.EntityKey);
    if (foundItem == null)
    {
        //INSERT
        foundItem = context.Set<T>().Add(item as T);
    }
    else
    {
        //UPDATE
        foundItem = item;
    }
    context.SaveChanges();
    return foundItem;
}

瞧!

答案 2 :(得分:0)

如果您使用自我跟踪实体,那么实体将跟踪状态并根据需要插入或更新,而无需使用单独的方法

相关问题