更新或插入导航属性

时间:2016-09-14 19:15:22

标签: c# entity-framework

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

如果我将此示例类建模为Property并使用Branch

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,以便框架知道不插入它,但有没有办法自动神奇地执行此操作?例如,不必每次插入Branch时都必须编写检查Property的bolierplate代码,以了解我是否需要Attach()它?

1 个答案:

答案 0 :(得分: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优化,因此如果仅“名称”或“分支”发生更改,则它将仅更新这些字段。无论如何 - 我希望这会有所帮助。