我发现自己经常需要EntityFramework中的“ Upsert”功能-我的父级+子级实体图断开了,我想“ upsert”父级(及其子级)。我的意思是
此“主要”的工作方式是保留父代的ID,但不保留子代的ID(在每个“ upsert”上为子代分配新的ID)。
public void Upsert(ParentEntity parentEntity) {
ParentEntity existing = DB.Parents.Find(parentEntity.Id);
if (existing == null) {
DB.Parents.Add(parentEntity);
} else {
var existingChildren = DB.Children.Where(m => m.ParentId == parentEntity.Id).ToArray();
foreach (var child in parentEntity.Children) {
child.ParentId = parentEntity.Id;
}
DB.Children.RemoveRange(existingChildren);
DB.Children.AddRange(parentEntity.Children);
DB.Entry(existing).State = EntityState.Detached;
DB.Parents.Attach(parentEntity);
DB.Entry(parentEntity).State = EntityState.Modified;
}
SaveChanges();
}
答案 0 :(得分:0)
这有效:
public void Upsert(ParentEntity parentEntity) {
ParentEntity existing = DB.Parents.Find(parentEntity.Id);
if (existing == null) {
DB.Parents.Add(parentEntity);
} else {
var newChildKeys = new HashSet<int>(parentEntity.Children.Select(m => m.Id));
var existingChildren = DB.Children.Where(m => m.ParentId == parentEntity.Id).ToArray();
var existingChildrenKeys = new HashSet<int>(existingChildren.Select(m => m.Id));
foreach (var existingChild in existingChildren) {
if (newChildKeys.Contains(existingChild.Id)) {
DB.Entry(existingChild).State = EntityState.Detached;
} else {
DB.Children.Remove(existingChild);
}
}
foreach (var child in parentEntity.Children) {
child.ParentId = parentEntity.Id;
if (existingChildrenKeys.Contains((child.Id))) {
DB.Children.Attach(child);
DB.Entry(child).State = EntityState.Modified;
} else {
DB.Children.Add(child);
}
}
DB.Entry(existing).State = EntityState.Detached;
DB.Parents.Attach(parentEntity);
DB.Entry(parentEntity).State = EntityState.Modified;
}
SaveChanges();
}
也许可以从样式角度进行改进/使其更通用。基本思想是
答案 1 :(得分:-1)
这是我用来获取想要的东西的东西。就我而言,它很棒:
$result = Customer::select(Customer::raw("SELECT
COUNT(CASE WHEN cityId IS NULL AND postCode IS NULL then 1 ELSE NULL END) as \"data1\",
COUNT(CASE WHEN cityId IN (123, 456) then 1 ELSE NULL END) as \"data2\",
COUNT(CASE WHEN cityId IN (789,999) then 1 ELSE NULL END) as \"data3\",
COUNT(CASE WHEN cityId IN (111, 222) then 1 ELSE NULL END) as \"data4\",
COUNT(CASE WHEN cityId IS NOT NULL AND cityId NOT IN (123, 456, 789, 999, 111, 222) then 1 ELSE NULL END ) as \"data5\"
from trial
"))->get();
这将分离数据库中已经存在的所有实体,这意味着它们将不会被处理。