使用实体框架从数据库中删除相关对象

时间:2017-08-29 21:42:31

标签: c# asp.net-mvc entity-framework

这是我在这个网站上的第一个问题。我在ASP.Net网络应用程序中自学MVC和实体框架。我有一系列相关实体,当我调用context.saveChanges()时,删除的相关数据项不会被删除。

我的实体 我有一个项目实体,可以有0到多个别名。这是数据库第一个项目,大部分代码都是自动生成的。

public Class Item
{
  public int Id{get;set};
  public string Name {get;set;}
  public virtual ICollection<AliasClass> AssociatedAliases {get;set;}
}

public Class AliasClass
{
  public int Id {get;set;}
  public int ItemId {get;set;}
  public string AliasName {get;set;}

  public virtual Item RelatedItem {get;set;}
}

好的,我们完成了自动生成的东西。我的回发操作接受回发视图模型。我正在实现存储库模式。我的物品回购有一个更新功能。

[HttpPost]
public ActionResult Edit (Models.EditViewPostBack MyPostBackModel)
{
  If (!ModelState.isValid){
    ... rebuild and copy  // this part works. Skipping over it
  }

  // this may be a key line of my issue
  MyPostBackModel.Item.Alias = MyPostBackModel.myAliases;
  ItemRepo.Update(MyPostBackModel.Item);
  return RedirectToAction("Index","Home");
}

这是Models.EditViewPostBack。新的关联列表将作为数组传回。新关联的id为0.在更新时,将为其分配一个真实的Id。

    public class EditViewPostBack{
      Item myItem {get; set;}
      AliasClass[] myAliases {get;set;}
    }

现在,最后是项目的核心和我真正的问题。这是ItemRepo中应该更新更改的方法。

    public void Update (Item myItem)
    {

      // myItem.AssociatedAliases contains only the wanted associations. 
      // It doesn't have the to-be deleted items. 
      // new items have an id of 0

      // defined in class constructor. 
      context.Item.Attach(myItem);
      context.Entry(Item).State = EntityState.Modified;
      foreach(var name in myItem.AssociatedAliases){
        // finds the modified local version of the item. doesn't connect
        // to the database to location info.
        if(name.id > 0)
        {
          var moded = context.AliasClass.find(name.Id); 
          context.Entry(moded).State = EntityState.Modified;
        }
        else
        {
          // it is brand new
          context.Item.Add(name)
        }
      }          
      //
      // Once the alias is not attached to it's item it has to go
      // How to handle deletes goes here
      //
      context.SaveChanges();
    }

因为实体状态未标记为已删除,关联仍然存在且项目显示为我从未删除过。我已经尝试了几件事。

如果我使用context.Alias.linqFunction()加载或搜索原始项目,则整个列表将与myItem参数重新关联,因为id匹配。

// invoking the following line causes Item.Alias to fully re-associate.
// I lose the list passed to the function 
context.AliasClass.Where(x=>x.ItemId == myItem.Id)

我目前无法加载别名,因为这将是数据库的往返,我不会删除该项目。

我想我需要一种删除方法,除非Id与仍然连接的列表匹配。但删除需要删除项目的实例。

如何从数据库中删除这些关联的别名?

1 个答案:

答案 0 :(得分:0)

您的问题是因为Aliases有三种情况 。它们可能是新的,也可能是编辑或混合的。因此,对于处理,您首先需要处理Aliases分隔的变更而不是Item为此,请创建新的Alias[],然后执行此操作:

    foreach(var name in myItem.Aliases){
             if it is edited one: update it
             if it is new one: save it with id of myItem
             }

然后在更新myItem之前,只需输入:

    myItem.Aliases=null;

如果你有一些被删除的Aliases,你就不能依靠EF不优雅来处理删除它们,就像你添加新的一样。您需要自己删除它们。 所以应该有像

这样的东西
allAliases=context.Getall(Aliases).where(they are for current item);

然后你可以

foreach(var aliase in allAliases){
         if it it isnot in myItem.Aliases: delete it
         }

为了获得更好的性能和更低的复杂性,我建议您先删除db中的所有Aliases,然后将所有myItem.Aliases作为新的myItem。因此,当您保存Aliases时,所有相关的isSelectedTab(b.itemFootballTypes, tab)将自动添加,您只需与db进行两次交互,这意味着更好的性能。