简体   繁体   English

更新实体和相关实体

[英]update entity and related entities

the scenario is: 情况是:

class Foo {
    [Key]
    public int Id { get; set; }
    public List<Bar> Bars { get; set; }
}

class Bar {
     [Key]
     public int Id { get; set; }
     public string Name { get; set; }
}

I must implement a simple crud ops like this: 我必须实现一个像这样的简单操作:

public void InsertOrUpdateFoo(Foo foo) {

    var db = new MyContext();

    //here some pseudocode
    if (foo exists) {

        d.Foos.Add(foo);

    } else {

        //here which is the best solution?
        //a good tradeoff between performance and code semplicity

        //case 1: delete first and add
        db.Foos.Remove(oldFoo);
        db.Add(foo);
        db.SaveChanges();

        //case 2: there is some functionality that allows you to update the entity like:
        db.Modify(oldEntity, newEntity);

    }

    db.Dispose();
}

In update scenario which seems to be the best choice? 在更新方案中,哪个似乎是最佳选择?

  1. Delete and Add 删除并添加
  2. Manage manually the update (foreach subentities) 手动管理更新(foreach子实体)
  3. Some other techniques?? 其他一些技巧?

Based on the idea in http://forums.asp.net/t/1889944.aspx , you could check to see if the ID property of the entity is a default value, such as 0 for an int. 根据http://forums.asp.net/t/1889944.aspx中的思想,您可以检查实体的ID属性是否为默认值,例如int为0。 If so, it's new and should be added. 如果是这样,它是新的,应该添加。 If not, then update it. 如果不是,则对其进行更新。

This can be indicated to the context by its EntityState , once the entity is attached to the context. 实体附加到上下文后,可以通过其EntityState指示上下文。 You can obtain access to this via the DbEntityEntry of the entity, through the context's Entry<T>() method. 您可以通过上下文的Entry<T>()方法,通过实体的DbEntityEntry获得对此的访问。

You'll also want to use the using statement when you create the context, which will manage the scope of the context and automatically call Dispose on it when the block ends. 您还需要在创建上下文时使用using语句,该语句将管理上下文的范围并在块结束时自动对其调用Dispose

It's better to split it up into the part that actually saves the changes as an insert or update (a repository method, most likely, but will use it stand-alone here for simplicity) and the code that manipulates the entity. 最好将其拆分为实际将更改保存为插入或更新的部分(很有可能是一种存储库方法,但为简单起见,在此单独使用)和操作实体的代码。

Definition of the method (based on your code): 方法的定义(基于您的代码):

public void InsertOrUpdateFoo(DbContext db, Foo foo) {        
    if (foo.ID == 0) { // assuming Foo's unique identifier is named ID
        db.Entry(entity).State = EntityState.Added;
    } else {
        db.Entry(entity).State = EntityState.Modified;
    }
    db.SaveChanges();
}

Usage: 用法:

// for when you're creating new entities
var newFoo = new Foo();
newFoo.Name = "A Name";
using(var context = new MyContext())
{
    context.Add(newFoo);
    InsertOrUpdate(context. newFoo);
}

// ...
// for when you're using existing entities
// you have an ID from somewhere in variable "id"
using (var context = new MyContext())
{
    var existingFoo = context.Find(id);
    if (existingFoo != null)
    {
        existingFoo.Name = "ChangedTheName";
        InsertOrUpdate(context, existingFoo);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM