实现Entity Framework 6 Add-or-Update方法的最简单方法是什么

时间:2015-05-12 16:07:30

标签: c# database entity-framework linq entity-framework-6

我有一个使用Entity Framework 6的项目,它为一堆不同的实体类型执行Add-or-Update(即Upsert)。对于这些实体中的每一个,都有代理整数ID(即主键),用于外部查找的自然键(例如客户ID)和一组描述性字段(例如名称,描述等)

我有一个AddOrUpdate方法,它查找自然键,查找数据库中的现有实体,并使用新值(如果存在)更新实体或创建新实体并将其添加到数据库(如果它还不存在的话。)

以下是我提出的方法示例(注意“key”是自然键,而不是代理ID):

public void AddOrUpdate(int key, string name)
{
    var customer = _database.Customers
        .FirstOrDefault(p => p.Key == key);

    var exists = customer != null;

    if (!exists)
        customer = new Customer();

    customer.Name = name;
    // Update other descriptive fields here

    if (!exists)
        _database.Customers.Add(customer);

    _database.Save();
}

代码工作正常,但总觉得有些乱。我很想知道是否有人用Entity Framework更好地解决这个问题,结构上更简单,读取更好,或者可以用更少的代码行完成(不牺牲可读性),并且仍然很容易进行单元测试。

如果是这样,请发布您对上述代码的重构,以便我可以从您的示例中学习。

1 个答案:

答案 0 :(得分:2)

EntityFramework已经为您实现了这一点,you can learn more about it here

void Main()
{
    using (AppContext context = new AppContext())
    {
        context.Users.AddOrUpdate(...);
    }
}

public class AppContext : DbContext
{
    public DbSet<User> Users { get; set; }


}

public class User 
{
    public string UserId { get; set; }
    public string Name { get; set; }
}

修改

这个答案已被投票两次,因为显然它不是线程安全的。对于少数人来说这可能是一个惊喜,但实体框架作为一个框架,并不是线程安全的。

MSDN DbContext - Thread Safety

  

此类型的任何公共静态(在Visual Basic中为Shared)成员都是   线程安全。 不保证所有实例成员都是线程安全的。

基本上,我的解决方案的线程安全性是无关紧要的,因为在并行线程中使用Entity Frameworks DbContext(特别是SaveChanges / SaveChangesAsync方法)会给你带来问题,开箱即用。