2017-08-29 87 views
0

这是我在这个网站上的第一个问题。我在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(); 
    } 

因为entitystate没有被标记为已删除,所以关联仍然存在,并且该项显示为我从未删除它。我已经尝试了几件事情。

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

// 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匹配仍然连接的列表。但删除需要删除项目的一个实例。

怎样才能从我的数据库中删除这些关联的别名?

回答

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 inelegance来处理删除他们,就像你添加新的那样。你需要自己删除它们。 所以应该有类似

allAliases=context.Getall(Aliases).where(they are for current item); 

然后你就可以有

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

为了获得更好的性能和更低的复杂性,我建议你先删除数据库中的所有Aliases,然后所有的myItem.Aliases会随着新的。所以当你保存你的myItem时,所有相关的Aliases都会自动添加,你只需要两次与db的交互,这意味着更好的性能。

+0

这不起作用。使myItem.Aliases null只删除与项目的关联,但不会将其从数据存储中删除。我需要别名不再与一个项目相关**获取**删除**。现在在Aliases表中有一个强制性的ItemId。但我确实看到了你在任何地方都使用别名/别名的观点。我会更新我的问题以使用更好的名称来防止混淆。 –

+0

@Michael我更新了我的答案。 – Hadee

+0

谢谢,Hadee。我之前尝试过这样的事情,但遇到了一个问题。您提出的解决方案将始终向数据库发出2个请求。这对于更新过程似乎非常低效。我以前遇到的问题是,当我加载其中itemid是当前项目的别名时,项目和别名之间的所有先前存在的关系都会突然出现在item.aliasclass中。那么我就会忽略需要添加,删除或更新的内容。 –