【问题标题】:Updating or inserting navigation property [duplicate]更新或插入导航属性 [重复]
【发布时间】:2016-09-14 19:15:21
【问题描述】:

我正在使用一个 web 服务,它将 xml 反序列化为用于构建实际 EF 数据模型的模型实例。

如果我有这个示例类使用Branch 建模Property

public class Property
{
    public int Id {get; set;}

    public int Name {get; set;}

    public string BranchId {get; set;}

    [ForeignKey("BranchId")]
    public string Branch {get; set;}
}

如果Branch 不存在于数据库中,好的,EF 会插入它。但是,如果是这样,我该如何指示 EF 进行更新?

我从例子中得到,你 Attach() 一个实体到一个 DbSet 以便框架知道不插入它,但是有没有办法自动神奇地做到这一点?例如,每次插入Property 时不必编写用于检查Branch 的样板代码以知道我是否需要Attach() 吗?

【问题讨论】:

  • 你描述的是一个Upsert。我认为这是一个重复的问题。我会这样标记它并在那里提供一个链接。
  • 现在如果我知道它被标记为Upsert,我可能不用发帖就能找到答案!感谢您的链接,非常有帮助。

标签: c# entity-framework


【解决方案1】:
public Task Upsert(Property property)
{
    using (var context = new SomeDbContext())
    {
        //if the id is autoincrement field then you will need to pass the new id to the property if it changes.
        await Save(new Branch{ Id = property.BranchId, Name = property.Branch}, context);
        await Save(property, context);
        await context.SaveChangesAsync();
    }
}
private Task Save(Property property, SomeDbContext context)
{   
    var existingProperty = context.Property.FirstOrDefaultAsync(f => f.Id == property.Id);
    if (existingProperty == null)
    {
        context.Property.Add(property);
    }
    else
    {
        //maybe use automapper here if there is a lot of this stuff going on
        //EF is smart enough to figure out what needs updating and will write a terse update statment
        //no attach is needed since your existingProperty still exist within your context
        existingProperty.Name = property.Name;
        existingProperty.BranchId = property.BranchId;
        existingProperty.Branch = property.Branch;
    }

}
private Task Save(Branch branch, SomeDbContext context)
{   

    var existingBranch = context.Branch.FirstOrDefaultAsync(f => f.Id == branch.Id);
    if (existingBranch == null)
    {
        context.Branch.Add(branch);
    }
    else
    {
        existingBranch.Name = branch.Name;
    }
}

我希望我已经理解了您的问题...这是我猜想的许多方法之一。这样做的好处是您的更新语句由 EF 优化,因此如果只有“名称”或“分支”发生更改,那么它只会更新这些字段。无论如何 - 我希望这会有所帮助。

【讨论】:

  • 你已经明白了,虽然我追求的是一些样板代码更少、更通用的东西,但我很感谢你花时间添加这个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多