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